Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

window.onerror not firing in Firefox

I'm trying to create a javascript error logging infrastructure.

I'm trying to set window.onerror to be my error handler. It works in IE 6, but when I run it in Firefox, it runs into some conflicting onerror method.

var debug = true;

MySite.Namespace.ErrorLogger.prototype = {

   //My error handling function.  
   //If it's not in debug mode, I should get an alert telling me the error.
   //If it is, give a different alert, and let the browser handle the error.
   onError: function(msg, url, lineNo) {
        alert('onError: ' + msg);
        if (!debug) {
            alert('not debug mode');
            return true;
        }
        else {
            alert(msg);
            return false;
        }
    }
}

//Document ready handler (jQuery shorthand)
$(function() {
    log = $create(MySite.Namespace.ErrorLogger);

    window.onerror = log.onError;

    $(window).error(function(msg, url, line) {
        log.onError(msg, url, line);
    });
});

If I use setTimeout("eval('a')", 1); where 'a' is an undefined variable, my error handler is what's fired (it works). However, my error-logger needs to catch all errors thrown by clients accessing the website, not just incorrect code in one place.

The code is on a .js page that is being called from the base page (C#) of a website. The site also uses jQuery, so I have a function that overrides the jQuery bind function, and that function works fine in both Firefox 3 and IE 6.

I know that Firefox is seeing the error because it shows up in both the Error Console and Firebug, but my window.onerror function is still not being called.

Any thoughts on how to override what Firefox is doing?

like image 214
elemjay19 Avatar asked Jun 17 '09 18:06

elemjay19


People also ask

What is window Onerror?

Introduction. onerror is a DOM event handler. It is started when an error occurs during object loading. While window. onerror is an event handler, there is no error event being fired: instead, when there is an uncaught exception or compile-time error, the window.

How does Onerror work?

The onerror event is triggered if an error occurs while loading an external file (e.g. a document or an image). Tip: When used on audio/video media, related events that occurs when there is some kind of disturbance to the media loading process, are: onabort. onemptied.

What is the use of JavaScript Onerror event?

What is onerror() Method in JavaScript? The onerror event handler was the first feature to facilitate error handling in JavaScript. The error event is fired on the window object whenever an exception occurs on the page.


1 Answers

The following is tested and working in IE 6 and Firefox 3.0.11:

<html>
<head>
<title>Title</title>
</head>
<body>
    <script type="text/javascript">
    window.onerror = function (msg, url, num) {
        alert(msg + ';' + url + ';' + num);
        return true;
    }
    </script>
    <div>
    ...content...
    </div>
    <script type="text/javascript">
    blah;
    </script>
</body>
</html>

If some other JavaScript library you are loading is also attaching itself to window.onerror you can do this:

<script type="text/javascript">
function addHandler(obj, evnt, handler) {
    if (obj.addEventListener) {
        obj.addEventListener(evnt.replace(/^on/, ''), handler, false);
    // Note: attachEvent fires handlers in the reverse order they
    // were attached. This is the opposite of what addEventListener
    // and manual attachment do.
    //} else if (obj.attachEvent) {
    //    obj.attachEvent(evnt, handler);
    } else {
        if (obj[evnt]) {
            var origHandler = obj[evnt];
            obj[evnt] = function(evt) {
                origHandler(evt);
                handler(evt);
            }
        } else {
            obj[evnt] = function(evt) {
                handler(evt);
            }
        }
    }
}
addHandler(window, 'onerror', function (msg, url, num) {
    alert(msg + ';' + url + ';' + num);
    return true;
});
addHandler(window, 'onerror', function (msg, url, num) {
    alert('and again ' + msg + ';' + url + ';' + num);
    return true;
});
</script>

The above lets you attach as many onerror handlers as you want. If there is already an existing custom onerror handler it will invoke that one, then yours.

Note that addHandler() can be used to bind multiple handlers to any event:

addHandler(window, 'onload', function () { alert('one'); });
addHandler(window, 'onload', function () { alert('two'); });
addHandler(window, 'onload', function () { alert('three'); });

This code is new and somewhat experimental. I'm not 100% sure addEventListener does precisely what the manual attachment does, and as commented, attachEvent fires the handlers in the reverse order they were attached in (so you would see 'three, two, one' in the example above). While not necessarily "wrong" or "incorrect", it is the opposite of what the other code in addHandler does and as a result, could result in inconsistent behaviour from browser to browser, which is why I removed it.

EDIT:

This is a full test case to demonstrate the onerror event:

<html>
<head>
<title>Title</title>
</head>
<body>
<script type="text/javascript">
function addHandler(obj, evnt, handler) {
    if (obj.addEventListener) {
        obj.addEventListener(evnt.replace(/^on/, ''), handler, false);
    } else {
        if (obj[evnt]) {
            var origHandler = obj[evnt];
            obj[evnt] = function(evt) {
                origHandler(evt);
                handler(evt);
            }
        } else {
            obj[evnt] = function(evt) {
                handler(evt);
            }
        }
    }
}
addHandler(window, 'onerror', function (msg, url, num) {
    alert(msg + ';' + url + ';' + num);
    return true;
});
</script>
<div>
...content...
</div>
<script type="text/javascript">
blah;
</script>
</body>
</html>

When the above code is put in test.htm and loaded into Internet Explorer from the local idks, you should see a dialog box that says 'blah' is undefined;undefined;undefined.

When the above code is put in test.htm and loaded into Firefox 3.0.11 (and the latest 3.5 as of this edit - Gecko/20090616) from the local disk, you should see a dialog box that says [object Event];undefined;undefined. If that is not happening then your copy of Firefox is not configured correctly or otherwise broken. All I can suggest is that you remove Firefox, remove your local profile(s) (information about how to find your profile is available here) and reinstall the latest version and test again.

like image 187
Grant Wagner Avatar answered Oct 02 '22 19:10

Grant Wagner