Exception Handling


Bullet-proof programs need to be able to anticipate runtime errors if they’re to work as they’re supposed to work in the real world because it’s inevitable that some runtime errors will occur. For example, a network resource might not be available because the network is down. Or maybe a file can’t be written to disk because the disk drive is full. Even with the best code in the world, these kinds of errors can happen.

And when code isn’t the best in the world, other kinds of errors can happen. For example, you may recall the code I presented near the beginning of this chapter that illustrated the pitfalls of naming a function dosomething and calling it in an onClick event using the case-variant name doSomething:

 function dosomething() {  }  ...  <INPUT type=button value="Click Moi" onClick="doSomething();"> 

When executed, as you’ll recall, this code caused an “Object expected” error (see Figure 10-5 and related text).

Conceptually, the right way to deal with runtime errors, and errors such as the “Object expected” error, is by using exception handling.

An exception is exceptional because it’s an unexpected condition, or error, in a program. It’s in the nature of life that some of these unexpected conditions can’t be anticipated. The point of exception handling is to deal with, or handle, all exceptions regardless of whether the exception can be reasonably anticipated.

In JavaScript, you accomplish exception handling by using the try and catch statement blocks and by using the properties of the JavaScript Error object.

Code placed in the try block is the main body of a function being monitored for exceptions.

Code placed in the catch block is executed in response to specific exceptions or as a general handler for all exceptions that aren’t specifically handled.

An example will make this clearer, but first let me make a couple of points: Many languages (but not JavaScript) provide the ability to add a Finally code block as well as try and catch blocks. The point of the Finally block is to provide a place for code that will execute no matter what happens in the other blocks of code. So code in the Finally block can be used for cleanup purposes, such as saving data or files and closing resources.

Caution

JavaScript didn’t implement try and catch statements until JavaScript version 1.2 (meaning Internet Explorer 5 and later and Navigator 6 and later), so if you’re using a browser that’s more than a few years old, there’s a chance that this code will not run in it.

Let’s take the dosomething function and modify it so that our click event calls a function named goodFunc, which in turn makes the call to doSomething. This will enable us to implement exception handling in the goodFunc function.

Here’s what the code looks like prior to the implementation of exception handling:

 function dosomething() {  }  function goodFunc(){        doSomething();  }  ...  <INPUT type=button value="Click Moi" onClick="goodFunc();">  ... 

If you run this code and click the button, you’ll get the “Object expected” error as explained earlier in this chapter.

Here’s the goodFunc function with try and catch blocks implemented:

 function goodFunc(){     try {        doSomething();     }     catch (e) {        if (e.description == "Object expected") {        alert("Cannot find a function named doSomething!");     }     else {        alert ("Other error" + e.description);      }    }  } 

Note that the catch statement block is passed the JavaScript Error object as an argument (e). A nice message is displayed if the error “caught” by the catch block is the “Object expected” error (see Figure 10-10).

click to expand
Figure 10-10: The “Object expected” error is caught and handled.

All other errors are handled in a generic fashion, with their description displayed.

Listing 10-10 shows the complete code for the example.

Advanced Caution

The object models of Internet Explorer and Netscape differ in respect to their Error objects. I leave it to you as an exercise to write the code that makes this example work with Netscape. True cross-browser Web applications written in JavaScript need to check which browser is running and conditionally execute the appropriate code for that browser.

Listing 10.6: Catching the “Object Expected” Error

start example
 <HTML> <HEAD> <TITLE>Don't bug me, please!  </TITLE> </HEAD> <BODY> <H1> <SCRIPT>  function dosomething() {  }  function goodFunc(){     try {        doSomething();     }     catch (e) {        if (e.description == "Object expected") {           alert("Cannot find a function named doSomething!");        }        else {           alert ("Other error" + e.description);        }     }  }  </SCRIPT> </H1> <FORM> <INPUT type=button value="Click Moi" onClick="goodFunc();"> </FORM> </BODY> </HTML> 
end example

Throwing Errors

As we’ve discussed, it makes sense to handle exceptions for several reasons. To recap, it’s better that end users don’t see the often-inscrutable error messages that JavaScript interpreters provide. If you’ve caught an error, you can also take remedial action to fix it in code or to keep track of the problem without bringing your program to a screeching halt. Finally, by throwing an error in appropriate circumstances, you can handle exceptions that are custom —meaning that the programmer, not the JavaScript interpreter, devised them. (Yet another reason to throw an error is to verify that exception handling is working.)

In this way, throwing custom exceptions, or errors, within a program can be used to handle extraordinary program conditions in an architecturally sane way. Actually, throwing an exception in code for this purpose is a lot like firing an event. If this is food for thought, have another look at Chapter 8, “ Understanding Events and Event-Driven Programming,” and compare and contrast exceptions and events. Please feel free to send me an email on the topic.

To Throw an Error:

  1. Create a form containing a text box for the error message and a button to throw the error:

     <FORM name="theForm">  Enter text for the error:  <INPUT type=text name=errText size=40> <INPUT type=button name=btnThrow value="Throw it!"> </FORM> 

  2. Add an onClick event handler to the button that invokes a function named throwError and pass it the value entered in the error text box:

     <FORM name="theForm">  Enter text for the error:  <INPUT type=text name=errText size=40> <INPUT type=button name=btnThrow value="Throw it!"     onClick="throwError(document.theForm.errText.value);"> </FORM> 

  3. Create the framework for the throwError function:

     function throwError(errString) {  } 

  4. Create a try...catch structure within the function:

     function throwError(errString) {     try {     }     catch(e){     }  } 

    The variable e is an implicit instance of the JavaScript Error object. Of course, you could use any other valid JavaScript identifier instead of e to refer to this instance of the Error object although it’s conventional to use something such as e or err.

  5. Create and throw the new Error instance that will be caught, providing an error number and the string passed to the function for the description:

     function throwError(errString) {     try {        throw new Error (42, errString);     }     catch(e){     }  } 

  6. When the error is “caught,” use an alert statement to display the error number and description:

     function throwError(errString) {     try {        throw new Error (42, errString);     }     catch(e){        alert("Error number: " + e.number + "; Description: " +  e.description)     }  } 

  7. Save the page (the complete source code is shown in Listing 10-7).

    Listing 10.7: Throwing an Error

    start example
     <HTML> <HEAD> <TITLE>Throw that error!</TITLE> <SCRIPT>  function throwError(errString) {     try {        throw new Error (42, errString);     }     catch(e){        alert("Error number: " + e.number + "; Description: " +  e.description)     }  }  </SCRIPT> </HEAD> <BODY> <H1>  Throw that error!  </H1> <FORM name="theForm"> <TABLE> <TR> <TD colspan=2>  Enter text for the error:  </TD> <TD> <INPUT type=text name=errText size=40> </TD> </TR> <TR> <TD colspan=2> </TD> <TD> <INPUT type=button name=btnThrow value="Throw it!"     onClick="throwError(document.theForm.errText.value);"> </TD> </TR> </TABLE> </FORM> </BODY> </HTML> 
    end example

  8. Open the page in a browser.

  9. Enter text for the error you want to throw and click Throw it! The error text you entered will be displayed in an alert box, proving that the error has been thrown and successfully caught (see Figure 10-11).

    click to expand
    Figure 10-11: The “Alas, I loved and lost!” error has been thrown and caught.

Error Catching

Error catching is often used to give particular errors or conditions special handling. For example, you might want to catch the condition in which an input string is equal to 42. If the string isn’t equal to 42, an exception, which isn’t handled, is generated. (More realistically, you might want to catch an error when program input is outside the required range.)

To Catch an Error:

  1. Create a form with a text input box and a button:

     <FORM name="theForm">  We can handle 42:  <INPUT type=text name=errText size=40 value="42"> <INPUT type=button name=btnThrow value="Catch it!"> </FORM> 

  2. Add an onClick event handler to the button that displays an alert box containing the return value of a function named catchError:

     <INPUT type=button name=btnThrow value="Catch it!"     onClick="alert(catchError(document.theForm.errText.value));"> 

  3. Create the framework for the catchError function:

     function catchError(errString) {  } 

  4. Create outer try and catch statement blocks to deal with general errors and if the string isn’t equal to 42:

     function catchError(errString) {     try {     }     catch (e){        return(e + " This one not handled here!");     }  } 

  5. Create inner try and catch statement blocks:

     function catchError(errString) {     try {        try {        }        catch(e) {        }     }     catch (e){        return(e.description + " This one not handled here!");     }  } 

  6. Within the inner try block, throw one error if the string is equal to 42 and a different error if it’s not:

     function catchError(errString) {     try {        try {           if (errString == 42)              throw new Error (42, "errString is 42 !");           else             throw new Error (0, "errString is NOT 42 !");       }       catch(e) {       }    }    catch (e){       return(e.description + " This one not handled here!");    }  } 

  7. In the inner catch block, check the error number:

     ...  catch(e) {     if (e.number == 42 )  }  ... 

  8. If the condition is the one we’re looking for—for example, the Number property of the Error object is 42—return an appropriate message. Otherwise, rethrow the error back up to the next highest handler (this is also called propagating the error):

     ...  catch(e) {     if (e.number == 42)        return (e.description + " Got this one!");     else        throw e; // re-throw the error  }  ... 

  9. Save the page (the source code is shown in Listing 10-8).

    Listing 10.8: Catching an Error

    start example
     <HTML> <HEAD> <TITLE>Catch that error!</TITLE> <SCRIPT>  function catchError(errString) {     try {        try {           if (errString == 42)              throw new Error (42, "errString is 42 !");           else              throw new Error (0, "errString is NOT 42 !");        }        catch(e) {           if (e.number == 42)              return (e.description + " Got this one!");           else              throw e; // re-throw the error        }      }      catch (e){         return(e.description + " This one not handled here!");      }  }  </SCRIPT> </HEAD> <BODY> <H1>  Catch that error!  </H1> <FORM name="theForm"> <TABLE> <TR> <TD colspan=2                                              >  We can handle 42                                               :  </TD> <TD> <INPUT type=text name=errText size=40 value="42"> </TD> </TR> <TR> <TD colspan=2> </TD> <TD> <INPUT type=button name=btnThrow value="Catch it!"     onClick="alert(catchError(document.theForm.errText.value));"> </TD> </TR> </TABLE> </FORM> </BODY> </HTML> 
    end example

  10. Open the page in a browser.

  11. With 42 entered in the text box, click Catch it! An alert box will display showing that this condition has been caught (see Figure 10-12).

    click to expand
    Figure 10-12: Error number 42 has been caught.

  12. With something other than 42 entered in the text box, click Catch it! An alert box will display showing that the exception has been propagated back to the general error handler (see Figure 10-13).

    click to expand
    Figure 10-13: The non-42 error is caught by the general handler.

start sidebar
The Error Object Across Browsers

As I noted earlier in this chapter, the Error object model used in these examples is specific to Internet Explorer. I leave it to you as an exercise to write code that performs similar functionality in Netscape as well! You should know, however, that if you treat an error as a simple text string— by assigning a text value to the error and testing for a specific error by comparing against the text string—the code will run on both browsers. I’ve focused on the Internet Explorer model because it will give you a better sense of what programming with structured exception handling is like in modern languages, without getting bogged down in too many language-specific details.

end sidebar




Learn How to Program Using Any Web Browser
Learn How to Program Using Any Web Browser
ISBN: 1590591135
EAN: 2147483647
Year: 2006
Pages: 115
Authors: Harold Davis

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net