reptile7's JavaScript blog
Monday, October 12, 2009
Error! Error, Will Robinson!
Blog Entry #159

Directly or indirectly, individually or in combination, user mouse and keyboard events underpin JavaScript's event handlers in almost all situations. However, there is one JavaScript event handler for which the user normally plays no role at all: onerror, which we'll briefly discuss today in looking over HTML Goodies' "The onerror Event Handler" tutorial.

(1) The onerror event handler was first implemented by Netscape in JavaScript 1.1; go here for the onerror section in the JavaScript 1.3 Client-Side Reference.
(2) onerror was subsequently picked up by Microsoft for MSIE 4; the current MSDN Library onerror page is here.
(3) As for the W3C, onerror does not appear in the "Intrinsic events" section of the HTML 4.01 Specification or in any of the XHTML 1.0 DTDs; however, the error event does crop up in the "HTML event types" subsection of the DOM Level 2 Events Specification.

Quoting Netscape, onerror [e]xecutes JavaScript code when an error event occurs; that is, when the loading of a document or image causes an error. Netscape associated onerror with the window object (not the document object) and the image object/element, as does Microsoft; in approximate correspondence, the W3C ties the error event to the HTML body, frameset, and object elements.

With respect to the window object, onerror is meant to flag syntax and run-time script errors of the types that we discussed all the way back in Blog Entry #4, and both Netscape* and Microsoft present an onerror example that uses onerror to display such errors to the user. The MSDN Library states, The onerror event fires for run-time errors, but not for compilation [syntax] errors. However, I can confirm that window.onerror does indeed catch syntax errors when using MSIE 5.2.3 for Mac OS X if the error and the error-handling function are in separate scripts:

<script type="text/javascript">
window.onerror = myBad;
function myBad( ) { window.alert("Syntax error!"); }
<script type="text/javascript">
document.write("This is a test.";

*Netscape alleges that its "Example 3: Error handling function", which we may go through later, will catch all of the script errors in a document; in practice, I am unable to reproduce Example 3's output with the browsers on my computer - only the noSuchFunction is not defined message, with an incorrect line number, shows up in the "Error Report" when using Firefox or MSIE.

window.onerror does not flag (X)HTML syntax errors, I'm sorry to report, e.g.:

<p id="p1'>This is a paragraph.</p>
<p id=="p1">This is a paragraph.</p>
<p id="p1">This is a paragraph.<\p>

With respect to the image object/element, onerror springs into action if either (a) there's something wrong with the image src value, or (b) the image file itself is corrupted in some way - check out Netscape's "Example 4: Event handler calls a function", which offers basic onerror code for bringing an image-loading problem to the user's attention.

Looking at the "Applies To" box at the bottom of the MSDN onerror page, I see that Microsoft claims onerror support for a number of other objects/elements; unfortunately, Microsoft provides no examples for these cases. (For example, Microsoft specifies that onerror can be paired with the script object/element. In this case, it's not clear if onerror is meant to catch bad content in an internal script and/or a bad src value for an external script. I tried both possibilities; neither attempt was successful, but perhaps this is a Windows thing.)

In "The onerror Event Handler", Joe uses onerror to take the user to a new page in response to a script error on the original page. Demo-wise, Joe provides a link to a jserrorpage.html page (you won't see this page if the demo works for you) whose source holds the scripts below:

<script type="text/javascript"><!--
window.onerror = redirect;
function redirect( ) { window.location = "errorfreepage.html"; }
// -->
<script type="text/javascript">

The first script element defines a redirect( ) function and also coassociates that function with onerror and the window object. In the second script element, the document.write( ) command is misspelled: when the browser hits this line, a run-time error is thrown and redirect( ) is triggered. Finally, redirect( ) sends the user to an errorfreepage.html page by assigning errorfreepage.html to the location property of the window object.

Firefox and MSIE run Joe's demo without incident, whereas Safari and Opera stall at the jserrorpage.html page. Subsequent experimentation has revealed that neither Safari nor Opera supports onerror for the window object, although they both support it for the image object/element.

Practical notes

• In another example, Netscape says, The onerror event handler for windows cannot be expressed in HTML. Therefore, you must spell it all lowercase and set it in a script [element]. On the other hand, the "Notes" section of Mozilla's current window.onerror page intimates that an onerror event handler is deployable as an attribute in the body element start-tag. I find that the window.onerror = redirect; script statement can indeed be replaced by

<body onerror="redirect( );">

when using Firefox but not when using MSIE, which is not so surprising given that the MSDN onerror page doesn't list the body object/element in the aforementioned "Applies To" box.

• Near the beginning of the tutorial, Joe says, JavaScript 1.1 allowed a new event handler named onerror. I've also seen it written onError and OnERROR. All three worked on my machines. It's true that alternate onerror capitalizations would be OK for an onerror HTML body or img element attribute - [HTML] Attribute names are always case-insensitive, the W3C declares - but in an object.onerror = funcRef; script statement, onerror must be all-lowercase per the Netscape quote in the preceding bullet point; the error-handling function will not 'listen' for error events if this is not the case.

• In its onerror "Description", Netscape states, window.onerror applies only to errors that occur in the window containing window.onerror, not in other windows. This does not mean that window.onerror will not catch errors in external scripts, which it will.

• Joe pitches his script as a means of preempting the display of error messages to the user:
It is my opinion that a user would much rather not see an error, that's why I like this simple little script so much...Because of the nature of the [script], the user may never even know that an error has occurred. There won't be an error box. There won't be the nasty little yellow triangle in the status bar. There won't be anything...except a new page.
Actually, MSIE users who have checked the Show scripting error alerts checkbox in the Preferences pane will still get an Object doesn't support this property or method run-time error dialog box before they are sent to errorfreepage.html; less obtrusively, Firefox users will see a document.wrte is not a function error message upon checking the Error Console. If you do want to 'turn off' these error notifications, however, you can do so by adding to the error-handling function a return true statement, which causes the function to override the browser's default error-handling mechanism:

function redirect( ) { window.location = "errorfreepage.html"; return true; }

Now, you may be thinking, "What is the point of this? A misspelling? You should be able to catch that before you upload your page" - at least that was my reaction when I first read the tutorial. Upon reading Joe's text more closely, however, a sentence in the first paragraph - No matter how careful you are, sometimes your pages throw errors - reminded me of something I observed regularly back in the day when I surfed the Web with my iMac 350: perfectly good code can throw errors with a browser that does not support that code.

In illustration, consider the following old-school example:

Let's suppose that it's March 1999 and that MSIE 5 has just been released. You augment your well-trafficked Web page with a script that utilizes the DOM getElementById( ) method, which is supported by MSIE 5 but not by earlier versions of MSIE. MSIE 4 users - and there'll be plenty of them out there - would definitely see an error message (if the Show scripting error alerts preference is enabled) when MSIE 4 hits the (first) getElementById( ) line in your script.

Joe's onerror script could then be employed as a sort of 'browser sniffer' to load an alternate page that won't cause any problems for MSIE 4 users who haven't upgraded to MSIE 5 yet. To take this concept a bit further, Joe himself recommends that his script be used to send users to a non-JavaScript version of the original page.

It is left to you to adapt the above example to other, more current situations; I won't tell you that onerror is an all-purpose tool for dealing with unsupported (new and/or proprietary) JavaScript features, but you should be able to use it for that purpose some of the time.

We'll discuss the use of error-handling functions to probe the details of error objects in the following entry.


Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)