Thanks for the response; it headed me in a good direction. I wasn't
sure how to use a Registry that avoided addEventListener, and I was
loathe to give up using window.onerror, but I figured I could overload
jQuery.fn.bind. It works! The "inside document ready handler and "bad
button error" errors end up getting tracked twice, but the second
report looks different from the first due to the addition of the url
and lineNo by the window.onerror call to trackError. And no error
escape notice, even in Firefox!
Thanks very much for your help.
-Joanna
Updated html/js code follows. Again, update the location of the
jquery.js and it should work fine.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Exception Example</title>
<script type="text/javascript" src="../script/third-party/
jquery.js"></script>
<style>
body { font-family: Tahoma, Arial, sans-serif }
div { margin: 20px }
div #errorConsoleMsg {
font-size: smaller;
font-weight: bold;
margin: 20px 60px 20px 60px; }
</style>
</head>
<body>
<div>
Examples of throwing errors from all the places I care about.<br /
Loading the page should generate two errors:
<ol>
<li>"outside document ready handler"</li>
<li>"inside document ready handler"</li>
</ol>
Clicking on the button should generate another: "bad button
error"<br />
<br />
The problem is that in Firefox, the error generated by clicking
the
button is lost. I want it to go through my trackError
function. It works fine in IE(6,7) because the window's
error event is triggered. But it never gets to my handler in
Firefox.<br />
</div>
<div id="badButtonDiv">
<button id="badButton">click me to generate an error</button>
</div>
<div>
If I open the
browser's error console, I can see that the error is caught by
someone:
<div id="errorConsoleMsg">
Error: [Exception... "'Error: bad button error' when
calling method:
[nsIDOMEventListener::handleEvent]"
nsresult: "0x8057001c
(NS_ERROR_XPC_JS_THREW_JS_OBJECT)"
location: "<unknown>"
data: no]
</div>
I just want it to be me.
</div>
<script type="text/javascript">
// The single point through which I want all errors to go
// err: a string or an Error object
function trackError( err )
{
var msg = 'Unknown error';
if ( err.message )
{
msg = err.message;
}
else if ( typeof err == 'string' || typeof err == 'String' )
{
msg = err;
}
alert( 'tracking error: ' + msg );
};
// override jQuery.fn.bind to wrap every provided function in try/
catch
var jQueryBind = jQuery.fn.bind;
jQuery.fn.bind = function( type, data, fn ) {
if ( !fn && data && typeof data == 'function' )
{
fn = data;
data = null;
}
if ( fn )
{
var origFn = fn;
var wrappedFn = function() {
try
{
origFn.apply( this, arguments );
}
catch ( ex )
{
trackError( ex );
// let error propogate; we didn't handle it, we
just tracked it
throw ex;
}
};
fn = wrappedFn;
}
return jQueryBind.call( this, type, data, fn );
};
// Attach trackError to window's onerror event;
// use onerror instead of $(window).error( ... ) in order to get
url and lineNo
window.onerror = function( msg, url, lineNo )
{
trackError( [ msg, url, lineNo ].join('; ') );
// let error propogate; we didn't handle it, we just tracked
it
return false;
};
$(document).ready( function() {
try
{
$('#badButton').click( function() { throw new Error("bad
button error") } );
throw new Error("inside document ready handler");
}
catch ( ex )
{
trackError( ex );
// let error propogate; we didn't handle it, we just
tracked it
throw ex;
}
} );
throw new Error("outside document ready handler");
</script>
</body>
</html>