Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firefox does not report exception when using JavaScript DOMContentLoaded with document.addEventListener

I am writing an internal framework that can have no dependencies (i.e. jQuery, etc.) and am trying to implement my own DOM ready-style functionality. It seems that when a callback in the ready queue (array of callbacks to complete on DOM ready), if an exception is thrown inside that function, execution stops and continues onto the next callback (which is what I want), but Firefox will not report the error (log to the console, trigger onerror, anything). Am I doing something wrong?

I have implemented this using a combination of a pattern by Dean Edwards (http://dean.edwards.name/weblog/2009/03/callbacks-vs-events/) and the jQuery source. I do not wish to implement just like jQuery because if one callback fails, the subsequent callbacks won't execute.

var readyCallbacks = [];

(function () {
    var currentHandler,
    fireReady,
    removeEvents,
    loopCallbacks = function () {
        for (var i = 0, len = readyCallbacks.length; i < len; i += 1) {
            currentHandler = readyCallbacks[i];
            fireReady();
        }
    };

    if (document.addEventListener) {
        document.addEventListener('readyEvents', function () { currentHandler(); }, false);

        fireReady = function () {
            var readyEvent = document.createEvent('UIEvents');
            readyEvent.initEvent('readyEvents', false, false);
            document.dispatchEvent(readyEvent);
        };

        removeEvents = function () {
            window.removeEventListener('load', loopCallbacks, false);
            loopCallbacks();
        };

        document.addEventListener('DOMContentLoaded', removeEvents, false);
        window.addEventListener('load', loopCallbacks, false);
    } else {
        // if < IE 9
        document.documentElement.readyEvents = 0;

        document.documentElement.attachEvent('onpropertychange', function (e) {
            if (e.propertyName === 'readyEvents')
                currentHandler();
        });

        fireReady = function () {
            document.documentElement.readyEvents += 1;
        };

        removeEvents = function () {
            window.detachEvent('onload', loopCallbacks);
            loopCallbacks();
        };

        document.attachEvent('onreadystatechange', removeEvents);
        window.attachEvent('onload', loopCallbacks);
    }
})();

Client.ready = function (callback) {
    readyCallbacks.push(callback);
};

Here is my test implementation. The console is written to and the DOM element has been manipulated. In IE error with the UNDEFINED_VARIABLE++; is shown in the console, but not in Firefox.

<!DOCTYPE html>
<html>
<head>
    <script src="Client.js"></script>
    <script>
        Client.ready(function () {
            console.log('logging before error');
            UNDEFINED_VARIABLE++; // This does not error in Firefox
            console.log('logging after error, not logged in Firefox');
        });

        Client.ready(function () {
            console.log('before DOM access');
            document.getElementById('cheese').innerHTML = 'cheese';
            console.log('after DOM access');
        });
    </script>
</head>
<body>
<div id="cheese">test</div>
</body>
</html>
like image 677
Eli Avatar asked Jul 22 '26 23:07

Eli


1 Answers

After some searching, this appears to be a known Mozilla bug: Errors thrown by handlers for custom events dispatched via dispatchEvent() are not logged properly in some versions of Firefox 3.x. This isn't a problem in your code, but in the browser implementation. If it's a real problem for you, you can wrap the handler in a try/catch block to identify and deal with errors:

document.addEventListener('readyEvents', function() {
    try { currentHandler() } catch (e) { console.log(e) }
}, false);

I have a jsFiddle here that demonstrates the problem with a simplified set of tests. Firefox correctly logs errors on handlers for built-in events like DOMContentLoaded and load, but misses the error when firing a handler for a custom event.

like image 175
nrabinowitz Avatar answered Jul 25 '26 12:07

nrabinowitz