Exceptions
As of JavaScript 1.4 exception handling has been added to allow you to capture and handle exceptions that occur in your JavaScript programs. The syntax that was chosen was the typical try...catch, throw, and finally statements that are found in other languages such as Java and C++. With these statements you can now throw your own errors, cleanly capture errors, and take the appropriate action based on the error thrown.
throw
The throw statement allows you to throw your own errors to be captured by the try...catch statement. The actual error that you throw can be any type of object so long as the try...catch statement knows how to handle the object. For example an error could be a number, string, or even a user-defined object that contains a number and an array of strings. The format of the throw statement resembles the following:
throw error
try...catch
The try...catch statement marks a block of code to try and a block of code to catch errors if an exception should be thrown. The format of the try...catch statement resembles the following:
try { code } catch (error) { code }
The try block consists of one or more lines of code enclosed by brackets just below the try statement, whereas the catch block consists of one or more lines of code enclosed by brackets just below the catch statement. The catch block can also be passed the actual error that was thrown by specifying an object to hold the error in parentheses. This error object can then be used within the catch block. The error object and parentheses are optional and are only needed if you intended to access the actual error thrown from the catch block.
If an exception is thrown in the try block or within a function called by a statement in the try block using the throw statement, the code in the catch block is executed immediately to handle the error exception that was just thrown. If no exception is thrown while the try block is executed, the catch block is skipped.
NOTE
The try...catch statement can be nested to provide even more error handling.
In Listing 3.6, the try...catch and throw statements are used to help validate passwords in a simple password validation program. If a password is less than 5 characters in length or greater than 10, the user is presented with an error message thanks to the try...catch block.
Listing 3.6 Password Validation Using the try...catch Block
<html> <script type="text/javascript" language="JavaScript"> <!-- hide function ValidatePassword(password) { try { //Make sure password has at least 5 characters if(password.length < 5 ) { throw "SHORT"; } //Make sure password has no more than 10 characters if(password.length > 10 ) { throw "LONG"; //too many characters } //Password ok alert("Password Validated!"); } catch(e) { if(e == "SHORT") { alert("Not enough characters in password!"); } if(e == "LONG") { alert("Password contains too many characters!"); } } } //--> </script> <h2>Password Validator</h2> <form name="myform"> Please enter password: <input type="password" name="password"><br><br> <input type=button name="validate" value="Validate!" onClick="ValidatePassword(myform.password.value)"> </form> </html>
Runtime Errors
In addition to capturing user-defined errors, the try...catch block can also capture runtime errors that JavaScript throws without the assistance of the throw statement. You can capture these errors using the try...catch block much as you would capture your own user-created errors. The ECMA-262 (Third edition) standard defines six types of error objects that can be thrown by JavaScript. These errors are shown in Table 3.9 with a short description of the type of error they represent.
Table 3.9 Runtime Errors
Error Name |
Description |
---|---|
EvalError |
The eval function was used in a way that is not defined. |
RangeError |
A numerical value exceeded the allowable range. |
ReferenceError |
An invalid reference value was detected. |
SyntaxError |
A parsing error occurred. |
TypeError |
An operand was a type that was not expected. |
URIError |
One of the URI handling functions was used in a way that is not defined. |
When a runtime error occurs, an Error object is returned. To determine the type of error, simply access the name property. Listing 3.7 purposely creates a runtime error by trying to use an undefined variable. The catch block determines the type error and displays an error message to the user.
Listing 3.7 Catching a Runtime Error
<html> <script type="text/javascript" language="'JavaScript"'> <!-- hide try { //The following line will create a type error //because the variable aNum is undefined. sum = 5 + aNum; document.write("sum=",sum); } catch(e) { if(e.name == "TypeError") { alert("A type error occurred."); } } //--> </script> </html>
finally
The finally block is an optional block of code that is executed each time an exception is thrown. This is especially useful in languages that work with files in which a file handle must be properly closed whether or not an error occurred. In the event that no error occurs, the code in the finally block is executed after the try...catch block but before the code following the try...catch block is executed. When an error is thrown, the finally block executes after the try...catch block. The format of the try...catch block plus the finally block looks as follows:
try { code } catch (error) { code } finally { code }
In Listing 3.8, the finally statement ensures that the password field is cleared whether or not the password is valid. If the password field had been cleared below the finally box, the field would only get cleared if the password was valid because there is a return statement in the catch block. If the password field had been cleared inside the catch box, the field would only get cleared if an error was thrown. Because the password field needed to be cleared regardless of errors, the finally block was used.
Listing 3.8 Password Validation Using the finally Block
<html> <script type="text/javascript" language="JavaScript"> <!-- hide function ValidatePassword(password) { try { //Make sure password has at least 5 characters if(password.length < 5 ) { throw "SHORT"; } //Make sure password has no more than 10 characters if(password.length > 10 ) { throw "LONG"; //too many characters } } catch(e) { if(e == "SHORT") { alert("Not enough characters in password!"); } if(e == "LONG") { alert("Password contains too many characters!"); } return(1); } finally { document.myform.password.value=""; } //Password ok alert("Password Ok!"); } //--> </script> <h2>Password Validator</h2> <form name="myform"> Please enter password: <input type="password" name="password"><br><br> <input type=button name="validate" value="Validate!" onClick="ValidatePassword(myform.password.value)"> </form> </html>