ChunkySoup.net Serving hearty nuggets since 2001

JavaScript Error Handling

Doing Something Else With The Error

Those familiar with JavaScript may already see how we can build in custom handling of the error after looking at the above example. What I have done is create a function called handleError() and set it to run each time an error occurs in the page. This function is no different then any other JavaScript function in that you can program it to do anything you'd like. While it is possible to move layers around, rewrite the whole document, or spawn 50 popup windows, I'd lean towards something simple and not prone to syntax errors or browser failings. In this next example I've replaced the browser's default message with my own alert message. [View Alert Example]

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>
<title>simple javascript error</title>
<script type="text/javascript">
<!-- //

function handleError() {
	alert("YOU HAVE ENCOUNTERED A JAVASCRIPT ERROR AND THIS PAGE WILL NOT WORK");
	return true;
}

window.onerror = handleError;
//-->
</script>


</head>
<body onload="doesnotexist()">

</body>
</html>

Although we've now replaced the browsers handling of the error with our own the alert message really doesn't help much. It is still awkward, intrusive, lacks any helpful information, and leaves the visitor sitting on a broken page.

Failing Gracefully With an Error Document

My favorite way to deal with an incapacitated page is to redirect the visitor to a friendly error message reminiscent of a 404 response. [View Redirect Example] This new document gives you ample room to explain what has happened. In your message it may be a good idea to explain the following:

  • If the document is information based then provide the visitor with alternate sources for the information found on the page with the error. Perhaps there is a text only or printer friendly version that resides elsewhere on the site.
  • If the document contains more of an experimental interactive piece, or is merely navigation to some other piece of information then say so. The visitor doesn't need to be worried that they're missing something if they're not.
  • Explain the technology used and why. If the script was written to follow current web standards as defined by the W3C recommendations mention that also.
  • Explain what browsers the document is known to work in and provide links.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>
<title>simple javascript error</title>

<script type="text/javascript">
<!-- //

function handleError() {
	window.location.replace("javascriptError.html");
	return true;
}

window.onerror = handleError;
//-->
</script>


</head>
<body onload="doesnotexist()">

</body>
</html>

Finding and Fixing The Error

While one should always code carefully and do rigorous testing it is nearly impossible to view a page on every existing browser/os platform before you release it to the public. So one can expect errors of some sort to occur. We just have to be alerted to the fact that someone encountered an error so that we know to fix it. This is the most difficult part of maintaining a web site because visitors never take the time to email you about problems with your site unless your site is the only place on the web to do what they need to do. (e.g. their online banking web site).

A large benefit of using the redirection technique above is that it give us a clue that the error is occurring. Specifically, the web server will log any requests for this newly created javascriptError.html document. A quick search through the log will give us all the times that a visitor encountered an error. The line you are looking for may look something like this.

127.0.0.1 - - [17/Nov/2001:17:55:38 -0500] "GET /basic/breakingjs/javascriptError.html HTTP/1.1 200 1124 "http://www.chunkysoup.net/basic/breakingjs/break_redirect.html" "iCab/2.6 (Macintosh; I; PPC)"

From this log entry for a request for the javascript error page one can see that a visitor using iCab v2.6 encountered a error on the site. We can then try and track down a copy of iCab, do some testing of your own and hopefully find a fix for the problem.

Your results may vary depending on what format your server logs requests in and what information different browsers report.

Taking this technique one final step further if we redirect the visitor to a server side script we can have that script email us a notification via email that there is a JavaScript error on the site. Depending on how often you read your site's logs this may save three or four weeks from going by before you notice the error. Since there are an enormous number of different server side technologies and since various servers support different combinations I really don't want to touch the topic in this article.

Why Bother?

While up front browser detection/redirection is a useful technique it is not always accurate. You can't test every User Agent in existence so a few browsers that might work get blocked and a few that don't get in. Using the onerror event to either suppress or react to errors provides an additional layer of protection.

The window.onerror event does not have to be the last line of defense in your scripting arsenal. When writing scripts that are intended only for use by standards compliant browsers it can also act as a poor man's exception handling and be your first line of defense.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>
<title>simple javascript error</title>

<script type="text/javascript">
<!-- //

function handleError() {
	window.location.replace("javascriptError.html");
	return true;
}

window.onerror = handleError;
//-->
</script>

<script type="text/javascript">
<!-- //

function changeParagraphColor() {
	var paragraphs = getElementsByTagName("p");
	for (i=0;i<paragraphs.length;i++) {
		paragraphs[i].style.color = "#FF0000";
		paragraphs[i].style.backgroundColor = "#0000FF";
	}

}

//-->
</script>

<style type="text/css">
<!--
p { color:#000000; background-color:#FFFFFF;}
-->
</style>

</head>
<body onload="changeParagraphColor()">
<p>paragraph 1</p>
<p>paragraph 2</p>
<p>paragraph 3</p>
<p>paragraph 4</p>
</body>
</html>

The above example shows a script that one would expect to cause errors in any User Agent that doesn't support the current standards. Instead if filling the document with a bunch of if statements checking each property before we use it the script just goes ahead and tries it. Failing to execute the script sends the visitor to a page much like they might if their browser support was checked ahead of time. [View Exception Example]

JavaScript 1.5 has introduced much better exception handling in the form of the try...catch block (which may be familiar to Java or C++ programmers). The use of the try...catch syntax is much more complicated then the onerror event so I'll leave its explanation to another article. If you'd rather not wait for me to get around to the topic some useful information can be found in the statements section of the Netscape Core JavaScript Guide.

Conclusion

Keep in mind that the ultimate goal of handling javascript error is to help the visitor deal appropriately with an error instead of leaving the site outright. If the page you are building will work regardless of JavaScript running or not just suppress the error and let the visitor get on with what they're doing. If the document must have javascript to be useful then instead of letting them continue to interact with a broken page cut them off. In doing so be sure to explain what is happening and give them the information they need to stay happy with you. Maybe you will keep a few more visitors then you would have otherwise.