Chapter 16. JavaScript Error Handling

After reading this chapter, you'll be able to

  • Understand error handling using JavaScript methods.

  • Handle errors using try/catch statements.

  • Use try/catch/finally statements.

  • Handle the onerror event for window and image objects.

An Overview of Error Handling

This chapter looks at two primary, built-in ways of handling error conditions in JavaScript. The try/catch statement pair is available in JavaScript. Many languages, such as Microsoft Visual Basic .NET, include this pair of keywords that help the programmer handle error conditions within their code.

Along with try/catch, JavaScript offers the onerror event, which gives the programmer another tool to perform an action when encountering an error.

Using try/catch

The try/catch set of statements enables a block of JavaScript to be executed and catches exceptions which the programmer can then handle. The code to do this follows this format:

try {
    // Execute some code
}
catch(errorObject) {
    // Error handling code goes here
}

The code within the try clause will execute and, should an error be found, processing is immediately handed over to the catch clause. Example 16-1 shows a simple example. (This can be found in the accompanying source code as listing16-1.htm.)

Example 16-1. A Basic try/catch Example

try {
    var numField = document.forms[0]["num"];
    if (isNaN(numField.value)) {
        throw "it's not a number";
    }
}
catch(errorObject) {
    alert(errorObject);
}

If the value of numField.value is not a number, a programmer-generated exception is thrown, the text of which reads, "it's not a number". The catch clause then executes, and in this case results in the appearance of an alert() dialog box. Note the difference between a programmer-generated exception and one that's generated by the JavaScript run-time engine, such as syntax errors. A try/catch block won't catch syntax errors, and as such, try/catch blocks provide no protection against these types of errors.

When using a catch clause, it's common to perform multiple tasks, such as calling another function to log the error or handle the condition in a general fashion. This is particularly helpful in problematic areas of code or in areas where the nature of the code (such as in code that processes user input) can lead to errors.

In this exercise, you'll build a Web form similar to the form that you built in Chapter 15. This time, in addition to providing visual feedback within the form's text field, you'll provide a bit of textual feedback.

Using try/catch with a Web form

  1. Using Microsoft Visual Studio, Eclipse, or another editor, edit the file number.htm in the Chapter 16 sample files folder.

  2. Within the Web page, add the code shown below in bold type:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/
    strict.dtd">
    <html>
    <head>
    <title>Try/Catch</title>
    <script type="text/javascript" src="number.js"></script>
    </head>
    <body>
    <form name="formexample" id="formexample-id002" action="#">
    <div id="citydiv-id002">Enter a Number Between 1 and 100: <input id="num" name="num"> <span
    id="feedback"> </span></div>
    <div><input id="submit-id002" type="submit"></div>
    </form>
    <script type="text/javascript">
    function init() {
        document.forms[0].onsubmit = function() { return checkValid() };
    }
    window.onload = init;
    </script>
    </body>
    </html>
  3. Create a JavaScript source file called number.js (also found in the source code as number.js).

  4. The first task is to convert the error handling code from Chapter 15 to the try/catch style and to match the content of this form. A try/catch isn't really required here, but this code does provide an easy-to-follow demonstration of this style in action. Within number.js, place the following code. (Although much of this code could be condensed into a single if statement, I've written several if statements here because we'll expand the code later in this exercise.)

    function checkValid() {
        try {
            var numField = document.forms[0]["num"];
            if (isNaN(numField.value)) {
                throw numField;
            }
            else if (numField.value > 100) {
                throw numField;
            }
            else if (numField.value < 1) {
                throw numField;
            }
            return true;
        }
        catch(errorObject) {
            errorObject.style.background = "#FF0000";
            return false;
        }
    }
  5. View the page in a Web browser. You should see this window:

    image with no caption
  6. Test the functionality of the new try/catch clauses. First, enter a number greater than 100 (say, 350) and click Submit Query. You should see a page like this:

    image with no caption
  7. Next, enter a phrase rather than a number and click Submit Query again. The form field should remain red.

  8. Now enter a number less than 1 and click Submit Query again. The form field should remain red.

  9. Finally, enter the number 50 and click Submit Query again. This time the form should submit successfully, which will result in a blank form.

  10. Modify the number.js file to add some textual feedback. The final number.js file should look like this:

    function checkValid() {
        try {
            var numField = document.forms[0]["num"];
            if (isNaN(numField.value)) {
                var err = new Array("It's not a number",numField);
                throw err;
            }
            else if (numField.value > 100) {
                var err = new Array("It's greater than 100",numField);
                throw err;
            }
            else if (numField.value < 1) {
                var err = new Array("It's less than 1",numField);
                throw err;
            }
            return true;
        }
        catch(errorObject) {
            var errorText = document.createTextNode(errorObject[0]);
            var feedback = document.getElementById("feedback");
            var newspan = document.createElement("span");
            newspan.appendChild(errorText);
            newspan.style.color = "#FF0000";
            newspan.style.fontWeight = "bold";
            newspan.setAttribute("id","feedback");
            var parent = feedback.parentNode;
            var newChild = parent.replaceChild(newspan,feedback);
            errorObject[1].style.background = "#FF0000";
            return false;
        }
    }
  11. Refresh the page in the browser so that a new version of the JavaScript executes. You won't notice any visible changes compared to the first time you loaded the form.

  12. Within the form, enter 350 and click Submit Query. Now you'll see a page like the following, with textual feedback next to the form field:

    image with no caption
  13. Next, enter -1 into the form and click Submit Query again. You'll see this page:

    image with no caption
  14. Now enter a text phrase into the form and click Submit Query again. You'll see a page like this:

    image with no caption
  15. Finally, enter a valid number between 1 and 100 (say, 50) into the form and click Submit Query. The form will submit without error.

This exercise used some of the methods explained in earlier chapters to create a new element and place it into the document to provide feedback. The first portion of the exercise converted the Web form found in Chapter 15 to the try/catch style and to the content of this form. Whereas the form found in Chapter 15 asked for a city to be entered, this form looks for a specific range of numbers to demonstrate multiple conditions for feedback.

Each condition throws an error with the numField object as its error object. Within the catch statement, the background color of errorObject changes to red and false is returned to indicate a failed or invalid form. The additional code used an array to join both a textual error and the form object (numField). This array object was then thrown to the catch statement. Its first index, 0, is the text for the error and the second index, 1, is the numField object, as shown here (pay particular attention to the code in bold):

try {
    var numField = document.forms[0]["num"];
    if (isNaN(numField.value)) {
        var err = new Array("It's not a number",numField);
        throw err;
    }
   else if (numField.value > 100) {
        var err = new Array("It's greater than 100",numField);
        throw err;
    }
    else if (numField.value < 1) {
        var err = new Array("It's less than 1",numField);
        throw err;
    }
    else {
        return true;
    }
}

The catch statement performs several duties in this exercise. First, it retrieves the <span> that will provide feedback to the user:

var feedback = document.getElementById("feedback");

Following this retrieval, a new text node is created using the text of the error message found in the errorObject:

var errorText = document.createTextNode(errorObject[0]);

A new span element is created so that it can be put into the document later. This span element, known within the code as newspan, has the error text appended and is then styled so that it stands out, with a red text color and bold font in this case. This new span is then given an ID of feedback, the same as the existing span element:

var newspan = document.createElement("span");
newspan.appendChild(errorText);
newspan.style.color = "#FF0000";
newspan.style.fontWeight = "bold";
newspan.setAttribute("id","feedback");

The feedback object has its parent node retrieved so that the replaceChild() method can be used. Then the replaceChild() method is used on the parent to replace the old span element with the new span element, as follows:

var parent = feedback.parentNode;
var newChild = parent.replaceChild(newspan,feedback);

Finally, the background of the text field in the form is colored red and false is returned to cancel submission of the form:

errorObject[1].style.background = "#FF0000";
return false;

Tip

The use of try/catch statements in this way helps to abstract the handling of exception cases within code. However, it does not prevent or provide assistance for syntax errors within the code.

And Finally…

There is an optional complementary statement in JavaScript that goes along with try/catch called finally. The finally statement contains code that gets executed whether or not the try statement's code succeeded or whether the catch handler executed. The finally block can be used to make sure that some code (such as cleanup code) will execute every time.

Example 16-2 (found in the source code as listing16-2.htm) shows the checkValid() function seen in previous exercises in this chapter with the addition of a finally statement:

Example 16-2. Adding a finally Statement onto the checkValid() Function

function checkValid() {
    try {
        var numField = document.forms[0]["num"];
        if (isNaN(numField.value)) {
            var err = new Array("It's not a number",numField);
            throw err;
        }
        else if (numField.value > 100) {
            var err = new Array("It's greater than 100",numField);
            throw err;
        }
        else if (numField.value < 1) {
            var err = new Array("It's less than 1",numField);
            throw err;
        }
        return true;
    }
    catch(errorObject) {
        var errorText = document.createTextNode(errorObject[0]);
        var feedback = document.getElementById("feedback");
        var newspan = document.createElement("span");
        newspan.appendChild(errorText);
        newspan.style.color = "#FF0000";
        newspan.style.fontWeight = "bold";
        newspan.setAttribute("id","feedback");
        var parent = feedback.parentNode;
        var newChild = parent.replaceChild(newspan,feedback);
        errorObject[1].style.background = "#FF0000";
        return false;
    }
    finally {
        alert("This is called on both success and failure.");
    }
}

Using the onerror Event

You may see the onerror event used within programs to provide a means to handle error events and conditions, though its use is becoming much less common now that there are less obtrusive ways of handling errors. The onerror event can be attached to the window and image objects.

Attaching onerror to the window Object

The onerror event is assigned a function that is called whenever an error occurs within the JavaScript. The onerror event can be helpful during development, though the use of tools like Firebug have lessened the need for it.

The onerror event is attached to the window object like this:

window.onerror = myErrorHandler;

The myErrorHandler variable refers to a user-defined function to handle the error condition. Three arguments are automatically sent to the error handler by the JavaScript interpreter:

  • A textual description of the error

  • The Uniform Resource Locator (URL) where the error occurred

  • The line on which the error occurred

If the error handler function returns true, JavaScript won't handle the error itself, assuming that the error has been taken care of by the error handler.

Example 16-3 (found in the source code as listing16-3.htm) shows an example of JavaScript and a user-defined handler.

Example 16-3. An Example of onerror in the window Object

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/
strict.dtd">
<html>
<head>
<title>onerror</title>
</head>
<body>
<div id="mydiv">Hi</div>
<script type="text/javascript">
function init() {
    doSomething();
}
function errorHandler() {
    alert(arguments[0] + " on line " + arguments[2]);
    return true;
}

window.onload = init;
window.onerror = errorHandler;
</script>
</body>
</html>

When viewed in a Web browser, an alert() dialog box like the one in Figure 16-1 appears.

An error handler using the onerror event of the window object

Figure 16-1. An error handler using the onerror event of the window object

Example 16-3 contains a purposefully undefined function within the init() function when the window loads. The JavaScript interpreter in turn throws the error when it finds the undefined function, and because a user-defined function called errorHandler is assigned to the onerror event, that function gets called. Within the function, an alert() dialog box is displayed and true is returned so that no further error handling will occur. The alert() dialog box displays the first and third indexes of the arguments array (arguments[0] and arguments[2]). The arguments array contains the three arguments sent to the error handler.

Ignoring Errors

Rather than handling errors with extra error-handling code, you can choose to ignore them entirely. This is accomplished simply by returning true from the error handler. Whenever true is returned from an error-handling function, the browser will behave as though the error has been handled. So by returning true, you're essentially just telling the interpreter to ignore the error.

Take a look at the code in Example 16-4. It's similar to that in Example 16-3; however, in Example 16-4, the only thing that the errorHandler function does is return true (as shown in bold type). This means that when the doSomething() function that's not defined would normally cause an error, it will be silently ignored instead. You can find the code for Example 16-4 in the accompanying source code as listing16-4.htm.

Example 16-4. Code that Silently Ignores an Error

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/
strict.dtd">
<html>
<head>
<title>onerror</title>
</head>
<body>
<div id="mydiv-id001">Hi</div>
<script type="text/javascript">
function init() {
    doSomething();
}
function errorHandler() {
    return true;
}

window.onload = init;
window.onerror = errorHandler;
</script>
</body>
</html>

You can see this behavior using Firefox with Firebug installed. First, load the code in Example 16-4 as is. You won't see any errors noted. Then comment the return true; statement from within the errorHandler function so it looks like this:

function errorHandler() {
//    return true;
}

When you reload the page, you'll notice an error in the Firebug error console, as shown in Figure 16-2.

Commenting out the return value from the error handler causes a JavaScript error that can be viewed using Firebug.

Figure 16-2. Commenting out the return value from the error handler causes a JavaScript error that can be viewed using Firebug.

Attaching onerror to the image Object

An onerror event can also be placed directly on image objects. When placed inline within the <img> tag, these event handlers can be used to handle images that aren't found.

For example, Figure 16-3 shows a page with a missing image.

A missing image that can be avoided using JavaScript

Figure 16-3. A missing image that can be avoided using JavaScript

The code for this page is shown in Example 16-5 (and in the source code as listing16-5.htm).

Example 16-5. A Page with a Missing Image

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/
strict.dtd">
<html>
<head>
<title>onerror</title>
</head>
<body>
<div id="mydiv-id002">Hi</div>
<img src="notfound.png">
</body>
</html>

Now consider the code with an inline onerror handler. The onerror handler points to an image that is found. The content of the image isn't important in this case, but using the onerror handler in such a way can help to prevent the "Image Not Found" icon from appearing within your Web pages. Example 16-6 (also in the source code as listing16-6.htm) shows the new code.

Example 16-6. Adding a onerror() Handler for the Image

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/
strict.dtd">
<html>
<head>
<title>onerror</title>
</head>
<body>
<div id="mydiv-id003">Hi</div>
<img src="notfound.png" onerror="this.src='logo.png'; return true">
</body>
</html>

When this page is loaded into a Web browser, the image still isn't found. However, in its place, an image called logo.png is retrieved, as shown in Figure 16-4.

The missing image has been replaced thanks to the onerror event handler.

Figure 16-4. The missing image has been replaced thanks to the onerror event handler.

Exercises

  1. Use an onerror event handler attached to the window object to handle errors when a function is undefined.

  2. Build a Web form and use a try/catch block to catch the case when a city entered into a text field is not "Stockholm". Provide visual feedback that the city was incorrect.

  3. Build a Web form and use a try/catch/finally block to catch a case when a number is greater than 100. Be sure that visitors are thanked every time that they use the form, no matter what they enter (either valid or invalid values).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.133.96