One JavaScript statement that rarely surfaces in the wild is throw(). The throw statement allows you to throw a formal error — sending details of the error to the browser’s error console — and halting further execution of the script.
The throw statement is particularly useful for APIs developers, as a way to warn its user-developers about runtime issues, such as missing or invalid input data. Its use should be generally preferable to alert() because it makes best use of the browser’s native functionality (and it’s less annoying):
if(typeof input == 'undefined')
{
throw('Missing input');
}
else if(parseFloat(input) != input)
{
throw('Input must be a number');
}
Using throw() with a string argument will throw a general error. However you can also create and pass an Error object, with which you can specify more details about the error:
var err = new Error();
err.name = 'My API Input Error';
err.message = 'Input must be a number';
throw(err);
The example above produces this output in Opera’s error console:
Firefox’s console doesn’t show the error name, only the message; but it’s still almost as useful:
The important thing to note is that anywhere you use throw() will halt the execution of the script (not just the enclosing scope). So you should arrange your code so that any throw() statement comes at the end of an execution block:
function err(type, message)
{
var err = new Error();
err.name = 'My API ' + type + ' Error';
err.message = message;
throw(err);
}
// the delete in this example won't happen
if(typeof this.input == 'undefined')
{
err('Input', 'Missing input');
delete this.input;
}
// but this delete will happen fine
if(typeof this.input == 'undefined')
{
delete this.input;
err('Input', 'Missing input');
}
Of course, a single language statement — however useful — can never replace a fully-featured debugging tool like Firebug; a proper debugger lets you set breakpoints, watchpoints, step-through execution … all kinds of goodness. Firebug even lets you log messages to its own console.
But Firebug is a browser-specific tool, where this is a cross-browser language feature, so it can be safely integrated into the heart of a script without any chance of unsatisfied dependencies.








August 22nd, 2008 at 2:44 pm
Firebug Lite is cross-browser…
http://getfirebug.com/lite.html
August 26th, 2008 at 7:04 pm
This blog is so off the mark I don’t know where to start. Throw is not a debugging tool. Use it to delegate unrecoverable errors to further up the chain of execution, where it may be handled more gracefully with a try catch. You should never intend for your thrown error to reach the surface.
August 27th, 2008 at 8:49 am
I second this… you are meant to handle the error with the try / catch, not just throw. Throw literally “throws” the exception string to catch, for the try / catch to handle gracefully.
August 27th, 2008 at 10:31 am
Yeah. I’m better at C++ but since learning that JS (ima newb) allows try catch blocks this was the first thing to come to mind when I read this. Seems to me you throw the error message and print it in the catch block. Correct me if I’m wrong. Even C++ error handling seems to be a foggy memory.
August 27th, 2008 at 11:33 am
Here’s a much better alternative. Continue to use the alert function as normal, but overwrite the alert function with a simple console logger. I find this to be quite useful, as there’s no legitimate usage of alerts in applications other than to annoy your users. I find it satisfying to destroy it it outright. When you’re done debugging, just replace alert with a stub function that does nothing. (or even silently ajax the alerts to a serverside error logger!) Here’s a simple one I threw together JUST NOW. No warrantees, only tested in firefox 3, not garaunteed to work anywhere. But give it a try, you might like it:
alert = (function () { var console = document.createElement("div"); console.setAttribute("id", "console"); console.setAttribute("style", "width:300px; height:300px; font-family: monospace; font-size: 10px; border: 1px solid black; background: white; position: absolute; right: 0; top: 0; overflow: scroll;"); document.body.appendChild(console); return function (s) { var p = document.createElement("p") p.appendChild(document.createTextNode(s)); console.appendChild(p); p.scrollIntoView(); } })()August 27th, 2008 at 2:49 pm
Apologies for the “inline” code. I didn’t notice the code block button!
August 27th, 2008 at 6:36 pm
I never said that throw was useful as a debugging tool. I said it’s useful as a high-level caretaker for other people using something you wrote.
I guess the post’s title is a bit off the mark.
August 28th, 2008 at 5:48 am
As Klas was saying… Firebug Lite is cross browser, he didn’t mention that you don’t need to run it on your server if you use a Bookmarklet to call it up. Save the javascript url below as a bookmarklet, and enjoy firebug anywhere, on any site.
Firebug Lite Bookmarklet
The only downside to this approach, is that you have to manually load firebug and anything that’s running before it’s loaded is not available (console, net transfers, etc…) which doesn’t help you if you have a window load or dom load based app to test.
August 28th, 2008 at 5:48 am
here’s the url for that bookmarklet since it looks like sitepoint’s comment system ate it.
javascript:var%20firebug=document.createElement(’script’);firebug.setAttribute(’src’,'http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js’);document.body.appendChild(firebug);(function(){if(window.pi&&window.firebug){firebug.init();}else{setTimeout(arguments.callee);}})();void(firebug);
August 28th, 2008 at 11:16 am
The DOJO framework provides a simple cross browser mechanism that creates a console in browsers like IE that do not natively support it. Then you can use something like:
console.debug(”Deleted record: ” + recordId);
August 28th, 2008 at 4:54 pm
The blog was useful in serving as a start for great discussion. so from that point of view - thanks; I’ve learnt some stuff here.
As for my 2cents worth well, I use Firebug to debug any pre-release code I have and then once I know it’s working correctly there some cross platform testing sees me right. All this means that the released code is working fine. JS is supposed to be cross-browser.
As for the earlier post from Breton that’s a great idea. We should never throw our error messages to users on the web. They are unliekly to report the problem and will simply get what they are after somewhere else. So if you must handle exceptions (my JS is a ll fairly simple) which is a good idea in more complex systems then a logging tool such as this is a great idea.
August 28th, 2008 at 6:02 pm
Instead of throw() function, I would rather use throw statement:
throw { name: 'My API Input Error', message: 'Input must be a number' };Compare it with more clumsy throw() function:
var err = new Error(); err.name = 'My API Input Error'; err.message = 'Input must be a number'; throw(err);September 11th, 2008 at 6:24 am
Greg said:
Umm, you do realize that
throwis a statement? Likereturn(which takes an optional argument),throwtakes one argument, which is expected to be an object constructed by Error. So your assertion thatthrow {object}is simpler, is simply wrong — you’re saying thatreturn 4;is simpler than
var i = 2; return(i+i);You can say, if you’d like:
throw new Error('My API Input Error','Input must be a number')