Debugging JavaScript: Handling Runtime Exceptions | WebReference

Debugging JavaScript: Handling Runtime Exceptions

By Rob Gravelle


It's surprising how many scripts don't incorporate proper exception handling. You can be as careful in your coding as you want, but sooner or later, something unexpected will come up and cause an exception to rear its ugly head! The Error object, available since JavaScript 1.5, is the solution. In Internet Explorer 5+ and Mozilla 1.0+, it provides a number of properties to help you display more meaningful error messages to the client and debugging information that is more useful to you, the developer. In the Debugging JavaScript: Understanding JavaScript Error Messages tutorial, we looked at the nature of exceptions in applications and discussed some of the more commonly encountered JavaScript errors. Today, we'll go over how to use the Error object to handle runtime exceptions.

The Try-Catch Block

The syntax of the try-catch block is ported over from the Java language. Any errors generated by code contained within the try's braces will execute the catch block, allowing for an alternate action or a graceful failure to occur. At the very least, a user-friendly message can be constructed and displayed to the client. Here is the basic syntax:

In the following example, the eval() function fails because the string won't evaluate to proper JavaScript code. Instead of allowing the browser to display some cryptic message or do nothing at all, we'll use an alert() to display a customized message:

And Finally...

The finally clause can be used to perform tasks, regardless of whether or not there was an exception. It's a good place to perform clean up or continue with procedures that don't depend on the contents of the try-catch block:

Be aware that there is nothing that can be done in the try-catch block to stop the finally from executing, including return statements. Therefore, the following should be avoided:

See the "Throwing Your Own Errors" section for a good example of the finally statement.

Exception Handling Anti-Patterns

An anti-pattern is a practice of coding something that appears obvious but is in fact ineffective or far from optimal in practice. Hence, anti-patterns ultimately produce more nasty side effects than benefits. With respect to exception handling, anti-patterns can emerge from consistent treating of errors as an afterthought to getting the script up and running smoothly.

Error Swallowing

Error Swallowing, or Error Hiding, results from the noble desire to avoid an application meltdown by dealing with it in the main function block or from passing partial information to an error handler sub routine. For instance, in the following code, the original error is lost because only the message is passed up the calling chain:

Another questionable use of the try-catch block is called the "do nothing" approach. Its defining feature is an empty catch block or one that contains a comment along the lines of "do nothing" or "ignore errors". In the following example, the coder has determined that the absence of the result string does not qualify as an error. To avoid an error condition, the individual checks for the result in the main code block and exits the function prematurely:

Although the developer has shown initiative by proactively handling a potential error, it will be difficult to debug the code in the event of abnormal behavior, as no error information is conveyed. Other problems with the above code are that:

  • the return statement without a variable will result in the function evaluating to the undefined constant. The return type should be a string. Supposed that the calling function's next line is something like formattedString.doSomething();. You can't call a function on the undefined object, while you can on an empty string (""). For this reason, the latter is preferred.
  • if many functions are working on the same string, it would be very difficult to pinpoint the one that caused the process to abort.