Error Handling

As programming languages like VBScript and JavaScript have become more complex and sophisticated, so too have the errors that programmers make when writing code. With error handling, however, you can write code into your script that traps errors and solves them internally or alerts the end user to the error with an informative message. For example, if a script calls an ActiveX control or Java applet that is not fully loaded, it would normally result in an error dialog being displayed to the user. This can be circumvented with error-handling code.

The onerror Event Handler

Handling the onerror event is one way to trap and work around scripting code errors. When an error occurs in a specified object, an onerror event is fired and the user is alerted. Objects that support onerror include the IMG, LINK, OBJECT, SCRIPT, STYLE, and, most useful of all, window objects. Netscape Navigator versions 3 and later and Internet Explorer versions 4 and later support onerror. Code Listing 10-2 shows a basic use of the onerror event. Figures 10-2 and 10-3 display the results.

Code Listing 10-2.

 <HTML> <HEAD> <TITLE>Listing 10-2</TITLE> <SCRIPT LANGUAGE="JavaScript"> function jHandleImageError(oImg){   alert(`Could not load the image `+oImg.name+". Loading alternate.")   oImg.src=`unavailable.gif' } </SCRIPT> </HEAD> <BODY> This image does not use an error handler. <IMG SRC="one.gif" NAME="ImageOne"><BR> This image does use an error handler. <IMG SRC="two.gif" NAME="ImageTwo" onerror="jHandleImageError(this)"> </BODY> </HTML> 

click to view at full size.

Figure 10-2. A programmed error message appears...

click to view at full size.

Figure 10-3. ...and then an alternate image is loaded.

When Code Listing 10-2 is run, it first attempts to load the images one.gif and two.gif, which can't be found, because neither image is included on the companion CD. The ImageOne object cannot load the one.gif graphic and fires the onerror event. No action is taken because there is no error handler on this image, so the user is left with only a missing graphic symbol. When the browser tries to load two.gif, the onerror event fires again. This time an in-line onerror event handler captures the error. The event handler calls a function that alerts the user with an error message and then loads an alternate graphic. The in-line event handler can also be used on OBJECT and SCRIPT elements to point to alternate resources when the browser is unable to load a file.

In the window object, onerror works to trap general errors. Code Listing 10-3 shows what happens when a page of script without error handling calls an object that does not exist.

Code Listing 10-3.

 <HTML> <HEAD> <TITLE>Listing 10-3</TITLE> </HEAD> <BODY> Clicking this button calls a nonexistent object. <FORM><INPUT TYPE="button" VALUE="Click Me" onclick="FakeO.use()"></FORM> </BODY> </HTML> 

click to view at full size.

Figure 10-4. The error dialog from Internet Explorer when Code Listing 10-3 is run.

When the user clicks the button, its onclick event handler attempts to use a method from an object that doesn't exist. This results in a standard undefined object error message being presented to the user, shown in Figure 10-4. The next code listing traps the error. The results are shown in Figure 10-5.

Code Listing 10-4.

 <HTML> <HEAD> <TITLE>Listing 10-4</TITLE> <SCRIPT LANGUAGE="JavaScript"> function errorHandler(msg,url,line) {   strPrompt=("Captured error \n"+msg+"\n on line "+line+" in "+url+".")   strPrompt+=("\nCancel display of standard error message?")   if (confirm(strPrompt)){return true}   else {return false} } window.onerror=errorHandler; </SCRIPT> </HEAD> <BODY> Clicking this button calls a non-existent object. <FORM><INPUT TYPE="button" VALUE="Click Me" onclick="FakeO.use()"></FORM> </BODY> </HTML> 

click to view at full size.

Figure 10-5. Code Listing 10-4 handles the error.

When Code Listing 10-4 is first loaded, an errorHandler function is added to the window object with the statement window.onerror=errorHandler. This statement means that whenever the window object fires the onerror event, the errorHandler function will be called. The errorHandler function takes three parameters that contain information about the error. The msg parameter contains the text of the error message, url provides the URL of the page in which the error occurred, and line provides the line number of the script that caused the error. These parameters are available only from an onerror event handler on the window object, not on other objects, such as images. Using these parameters, the function then formats and presents an error message to the user, along with the option to cancel the default error message. If the errorHandler function returns the value true, the window object will not display an additional error message. If false or no value is returned, the regular error message will be displayed. The errorHandler function can also prevent any error message from being displayed with a return true statement, or by setting the window.event.returnValue property to true.

In addition to the in-line onerror event handler demonstrated in Code Listing 10-2 and the window.onerror handler shown in Code Listing 10-4, you can create a specific script block containing the error-handling code, as follows:

     <SCRIPT LANGUAGE="JavaScript" FOR="window" EVENT="onerror(msg,url,line)">     [...script commands...]     </SCRIPT> 

This type of script block works only in Internet Explorer, not in current versions of Netscape Navigator.

The try...catch and throw Statements

A new mechanism for error handling that is currently supported in the JScript 5 script engine, which comes with Internet Explorer 5 and can be used in IIS and earlier versions of Internet Explorer, is the try...catch statement. It is very useful when running script on the server, where there is no window object. It is also handy because different error-handling code can be placed around different problem areas. Code Listing 10-5 shows a try...catch statement. Figure 10-6 displays the results.

Code Listing 10-5.

 <HTML> <HEAD> <TITLE>Listing 10-5</TITLE> <SCRIPT LANGUAGE="JavaScript"> try {   document.write("This statement works.")   document.write(fakeO.use())   document.write("This statement does not work.") } catch (e) {   strError=("An error occurred. The error number was "+e.number+". ")   strError+=("The error message was \""+e.description+"\"")   alert(strError) } </SCRIPT> </HEAD> <BODY> </BODY> </HTML> 

click to view at full size.

Figure 10-6. Code Listing 10-5 handles an error with a try...catch statement.

As the page is being loaded, the script block is run. As you can see, the script begins with a try block, which contains a series of statements that the browser attempts to run. If any of the statements results in an error, the error is trapped and passed to the subsequent catch block, which constructs and displays an error message.

The first statement in the try block is a document.write method that has no errors and is executed successfully. The second line calls on an object and a method that do not exist. This causes an error, and so the catch block is called, which constructs and then displays an error message.

The catch statement is automatically passed a parameter that contains an error object. This object has two properties, number and description. Each type of script error is assigned a unique error number. The number property can be tested and can cause different effects depending on the error. The description property contains a textual description of the error.

The try...catch statement is especially useful on the server side, where there is no window object to trap errors. It can also be used to set default values. For example, the following statement will assign the value of b to a, unless there are any problems doing so (for instance, if b doesn't exist), in which case a will be assigned the value 5 instead.

 try {a=b} catch {a=5} 

The throw statement can be used to pass a specific error message to a catch statement. It can also be used to pass an error to a higher-level error handler in the case of nested try...catch statements. Code Listing 10-6 demonstrates both of these techniques.

Code Listing 10-6.

 <HTML> <HEAD> <TITLE>Listing 10-6</TITLE> <SCRIPT LANGUAGE="JavaScript"> processedSuccessfully=false sProb="" while (!processedSuccessfully){   try {     try {       intInput=prompt(sProb+"Enter a number to divide into 100.",4)       // send specific error to inner handler       if (isNaN(intInput)){throw "NaN"}       if (intInput==0){throw "div0"}       x=(100/intInput)       sOutput=("100 divided by "+intInput+" equals "+x)       processedSuccessfully=true     }     catch(e) {       sErr="Handled in inner handler. "       if (e == "NaN"){         sProb=(sErr+"You did not enter a valid number.\n")       }       // send other errors to outer handler       else{throw e}     }   }   catch(e) {     sErr="Handled in outer handler. "     if (e=="div0"){       sProb=(sErr+"You entered 0, which cannot be a divisor.\n")     }   else{sOutput=(sErr+e.description);break}   } } document.write(sOutput)   </SCRIPT> </HEAD> <BODY> </BODY> </HTML> 

Code Listing 10-6 begins by prompting the user for a number. The code uses a while loop that continues to prompt the user until a number is entered that meets the code's requirements, or until a break statement is called that takes the user out of the while loop. When a valid number is entered, the code divides the number into 100 and adds the result to the sOutput variable, which is then written to the browser window.

There are, however, several predictable user input errors that could upset this process. A user could, for instance, enter 0, which does not divide meaningfully into 100, or the user could enter text instead of a number. Additionally, some type of unexpected error could occur. As a result, we've utilized the try, catch, and throw statements in our code to test for, capture, and report these types of errors.

The inner try statement tests whether the user entered data that is not a number and whether the number entered is 0. If either of these situations occur, the throw statement is used to send information about the error to the catch statement, which creates and displays a specific error message. If any other errors occur, they are automatically sent to the catch statement, as usual.

If the user enters a non-number (text or symbol) string, the inner catch statement detects this error and adds it to the sProb variable, which is appended to the prompt when the user is next asked for a number. If the user enters 0, the error is thrown to the outer catch statement, which also modifies the sProb variable. Any other errors are described in the sOutput variable, after which the break statement is used to exit the while loop. The document.write method then describes these errors on the screen. To cause such a problem, copy the listing to your hard drive and comment out the line that reads x=(100/intInput). This will cause an `x' is undefined error message to display.

More About the number Property

The JScript scripting engine inside Internet Explorer can return the errors shown in Table 10-1. This table does not list errors returned by objects that are external to the scripting engine (like the Media Player and other ActiveX controls) and that can return their own custom errors.

Table 10-1

Error Number Error Description
5 Invalid procedure call or argument
6 Overflow
7 Out of memory
9 Subscript out of range
10 This array is fixed or temporarily locked.
11 Division by zero
13 Type mismatch
14 Out of string space
17 Can't perform requested operation
28 Out of stack space
35 Sub or Function not defined
48 Error in loading DLL
51 Internal error
52 Bad file name or number
53 File not found
54 Bad file mode
55 File already open
57 Device I/O error
58 File already exists
61 Disk full
62 Input past end of file
67 Too many files
68 Device unavailable
70 Permission denied
71 Disk not ready
74 Can't rename with different drive
75 Path/File access error
76 Path not found
91 Object variable or With block variable not set
92 For loop not initialized
93 Invalid pattern string
94 Invalid use of Null
322 Can't create necessary temporary file
424 Object required
429 Automation server can't create object
430 Class doesn't support Automation
432 File name or class name not found during Automation operation
438 Object doesn't support property or method <item>
440 Automation error
445 Object doesn't support this action
446 Object doesn't support named arguments
447 Object doesn't support current locale setting
448 Named argument not found
449 Argument not optional
450 Wrong number of arguments or invalid property assignment
451 Object not a collection
453 Specified DLL function not found
458 Variable uses an Automation type not supported in JScript
501 Cannot assign to variable
502 Object not safe for scripting
503 Object not safe for initializing
504 Object not safe for creating
5000 Cannot assign to `this'
5001 <Item> is not a number; Number expected
5002 <Item> is not a function; Function expected
5003 Cannot assign to a function result
5004 <Item> is not an indexable object; Cannot index object
5005 <Item> is not a string; String expected
5006 <Item> is not a date object; Date object expected
5007 <Item> is not an object; Object expected
5008 Cannot assign to <item>; Illegal assignment
5009 <Item> is undefined; Undefined identifier
5010 <Item> is not a boolean; Boolean expected
5011 Can't execute code from a freed script
5012 Cannot delete <item>; Object member expected
5013 <Item> is not a VBArray; VBArray expected
5014 <Item> is not a JScript object; JScript object expected
5015 <Item> is not an enumerator object; Enumerator object expected
5016 <Item> is not a regular expression object; regular expression object expected
5017 Syntax error in regular expression
5018 Unexpected quantifier
5019 Expected `]' in regular expression
5020 Expected `)' in regular expression
5021 Invalid range in character set

You will notice that the numbers reported in this table differ substantially from those reported by the actual number property. Code Listing 10-7 demonstrates how to convert the number reported in the number property to the one shown in the chart above. Figure 10-7 displays the results.

Code Listing 10-7.

 <HTML> <HEAD> <TITLE>Listing 10-7</TITLE> <SCRIPT LANGUAGE="JavaScript"> try {   x=y } catch (e) {   strError=("An error occurred. error.number was "+e.number+"\n")   strError+=("Convert this and get "+(e.number&0xFFFF)+"\n")   strError+=("The error message was \""+e.description+"\"")   alert(strError) } </SCRIPT> </HEAD> </HTML> 

Figure 10-7. Code Listing 10-7 converts an error to the value shown in Table 10-1.

The technical explanation for this is as follows. The numbers in Table 10-1 represent only the lower order bits of the number in e.number. The second line that references e.number performs a bitwise AND operation with the & operator to retrieve only the lower order bits. This is also known as performing a bit mask. You can find out more about the & operator at msdn.microsoft.com/scripting, where you can also find more information about handling errors.

So far, we've looked at some functions and features of HTML and scripting. Part 3 introduces Cascading Style Sheets (CSS), a technology that has been around since Internet Explorer 3 but that has been greatly expanded since then. CSS gives you extensive control over the appearance of your pages and makes it easy to give an entire Web site a consistent look and feel.



Dynamic HTML in Action
Dynamic HTML in Action
ISBN: 0735605637
EAN: 2147483647
Year: 1999
Pages: 128

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