If you develop for the mozilla platform, you might be used to error messages like the above. (Or you might wish you got error messages like the above…) An uncaught javascript exception has resulted in a message in the error console as well as some equivalent stdout spew because it’s a debug build. While any error is better than no error, it doesn’t exactly narrow down how we got there.
Wouldn’t it be nice if we got back-traces for these errors?
The future is now, people! And it comes in the convenient form of a patch against the 1.9.1 branch, just like you always dreamed! Also, an extension.
Currently (pre-patch), there are basically 3 ways scripting errors can show up in the platform:
- nsIScriptError instances. These are what show up on the error console. These have information equivalent to a single stack frame.
- nsIException instances. These can provide a stack in the form of an nsIStackFrame chain (the same thing Components.stack gives you). These get converted into nsIScriptError instances when it comes time to report them to the error console. From a stack perspective, only XPConnect produces nsIException instances with stack traces, although you can make your own via Components.Exception. A fundamental limitation of these stack traces is that they are only constructed from live JS call stacks, so if a JS exception has unwrapped its way to the top-level you are out of luck.
- JavaScript Error instances. These have a private super-rich (it even knows arguments!) call-stack that can only be exposed as a string via the non-standard stack attribute. XPConnect understands JS error reports (the ‘flat’ mechanism by which SpiderMonkey reports errors/exceptions to C++ code), but it has no clue about exceptions and their Error form of existence. The exceptions in their error report guise are converted into nsIScriptError instances.
What the patch (on bug 493414) does is:
- Introduce an nsIScriptErrorEx interface that extends nsIScriptError to provide a ‘location’ attribute like nsIException which is an nsIStackFrame.
- Modify nsScriptError to implement the extended nsIScriptErrorEx. Alternatively, I could have made XPConnect’s nsXPCException class implement nsIScriptError or nsScriptError also implement nsIException or something like that and not introduced nsIScriptErrorEx at all.
- Modify all nsIScriptError-creation sites that I care about (I’m not looking at you, DOM workers) to try and provide or propagate existing nsIStackFrame information.
- If a JS stack frame is not available, but an exception is in the form of a JS error, suck the call stack out of it. Theoretically, this should not be a fallback but rather the default case, but it depends on some JS/XPConnect implementation details I am trying to avoid finding out about for now.
- Modify the JS API to provide call stack sucking functionality.
- Does various sketchy things to expose XPCJSStack::CreateStack from XPConnect to the error reporters in other modules. If you thought the choice of creating nsIScriptErrorEx was sketchy, welcome to the Downtown East Side of dubious patches. I expect there is no chance of it working on Windows because of this, and you may be out of luck on OS X. Behold your comeuppance, popular platforms!
What the extension (repo) does is:
- Add an nsIConsoleListener at app-startup that is aware of nsIScriptErrorEx and knows how to generate totally wicked 256-color ANSI escape sequences.
- Not expose the stack traces in the error console. The error console is for suckers who don’t have impossibly fast reflexes and a love of XON/XOFF flow control.
- Only target Thunderbird. Behold your comeuppance, all other mozilla applications! (The extension wizard didn’t know how to do the thing that makes it work on all xulrunner-based things… feel free to push a fixed install.rdf to my repo.)
I have logged bug 493414 to hold the patch and hopefully track the effort moving forward.
great stuff 🙂
> (The extension wizard didn’t know how to do the thing that makes it work on all xulrunner-based things
https://developer.mozilla.org/en/Install_Manifests#targetApplication says: “Gecko 1.9 based applications allow you to use the special targetApplication id toolkit@mozilla.org to say that the add-on is compatible with any toolkit app with a toolkit version matching the minVersion and maxVersion.”
This extension is pretty nice, even if you do need to use flow control. The full patch will rock.