Update: Safari 5.1 added support for onerror, so this post is now mostly superfluous.
By default, most browsers hide un-handled Javascript errors from end users. Typically, the error is logged to a Javascript console which can only be viewed via developer tools. This is reasonable behavior for a production web site. However, during development and testing, it is better to receive an immediate, visible notification of any error, since the console is too easily forgotten or ignored.
Unfortunately, there currently isn’t a widely supported, standard way to trap all un-handled exception. The HTML standard defines window.onerror, but it is implemented inconsistently (IE, Firefox, Chrome), or not at all (Safari, Opera).
GenericOnError fills this gap with some kludgy hackery, by browser sniffing and patching the un-documented Error callback found in Safari and Opera to emulate a simplified version of window.onerror. Here’s a test page and the code:
GenericOnError Test Page
function genericOnError(handler) {
// Chrome, Firefox and IE implement onerror,
// and it will one day be standardized...
window.onerror = function (message, url, line) {
handler("Error: " + message + " " + url + ":" + line);
// Note, don't return a value since Chrome/Firefox don't agree
// on true/false meaning. A no-return triggers the correct
// behavior in both (print error to console).
}
// Safari 5 and Opera 11 doesn't implment onerror,
// so intercept the undocumented Error function
if (RegExp("Safari|Opera").test(navigator.userAgent)
&& !RegExp("Chrome").test(navigator.userAgent)) {
var originalError = window.Error;
window.Error = function() {
if (arguments.length > 0) handler("Error: " + arguments[0]);
return originalError.apply(this, arguments);
}
}
}
genericOnError(function(m) { alert(m); });
throw new Error("test error");
GenericOnError has been tested on the current releases of IE, Firefox, Chrome, Safari and Opera. GenericOnError should only be used for development testing, since it is likely to break catastrophically in future browser releases.