Whilst try ... catch
will work on the code that the script runs initially, as Jenita says it won't catch Syntax Errors, and also it won't catch errors thrown by callback functions which execute later (long after the try-catch has finished). That means no errors from any functions passed to setTimeout
or addEventListener
.
However, you can try a different approach. Register an error listener on the window.
window.addEventListener("error", handleError, true);
function handleError(evt) {
if (evt.message) { // Chrome sometimes provides this
alert("error: "+evt.message +" at linenumber: "+evt.lineno+" of file: "+evt.filename);
} else {
alert("error: "+evt.type+" from element: "+(evt.srcElement || evt.target));
}
}
This will be called when an exception is thrown from a callback function. But it will also trigger on general DOM errors such as images failing to load, which you may not be interested in.
It should also fire on Syntax Errors but only if it was able to run first so you should put it in a separate script from the one that may contain typos! (A Syntax Error later in a script will prevent valid lines at the top of the same script from running.)
Unfortunately, I never found a way to get a line number from the evt
in Firefox. (Edit: Poke around, I think it might be there now.)
I discovered this when trying to write FastJSLogger, an in-page logger I used back when the browser devtools were somewhat slow.
Desperate to catch line numbers, I started to experiment with wrappers for setTimeout
and addEventListener
that would re-introduce try-catch around those calls. For example:
var realAddEventListener = HTMLElement.prototype.addEventListener;
HTMLElement.prototype.addEventListener = function(type,handler,capture,other){
var newHandler = function(evt) {
try {
return handler.apply(this,arguments);
} catch (e) {
alert("error handling "+type+" event:"+e.message +" linenumber:"+e.lineNumber);
}
};
realAddEventListener.call(this,type,newHandler,capture,other);
};
Obviously this should be done before any event listeners are registered, and possibly even before libraries like jQuery are loaded, to prevent them from grabbing a reference to the real addEventListener
before we have been able to replace it.