Reputation: 25287
I want to be able to send myself all the javascript errors on a page. I am an extension developer, so the following has an emphasis on making sure the dom is ready before making calls to it.
I investigated adding some functionality to the throw
to also send or mail the exceptions, but I didn't find this to be possible.
1:main solution to this, a window.onerror handler:
window.onerror = function(e, url, line){
mailError('onerror: ' + e + ' URL:' + url + ' Line:' + line);
console.error('\nLine ' + line + ':');
setTimeout(function(){retry();}, 100); //mainly useful in content scripts for extensions,
return true;
}
May also need to do same thing via jQuery:
$(window).error(
function(e, url, line){
//handle error
}
);
The downfall of this is that your code has stopped executing.
To avoid errors stopping execution, it's best to use callbacks to make sure code executes in a certain sequence, and to utilize events wherever possible. You can also protect dom calls with a few techniques
$(document).ready({
//you usually won't get bad dom calls wrapping your code in this
});
You can also consider running code on window.onload
window.onload = function(){
//you page will probably twitch upon executing code at this time
//but you will almost never have a bad dom call
};
Another technique
if (document.getElementById('iNeedThisElement')) {
//doin work!
document.getElementById('iNeedThisElement').style.display = 'block';
} else {
var stillNeedToTakeCareOfX = true; //false otherwise since it's undefined
mailError('iNeedThisElement was unavailable...');
}
Using these techniques and just debugging your application, you should be fairly well off. Since console.error, .warn, and .log statements cannot be retrieved and reported back to your, a small alternative suite is provided below:
var Xe = { }; //Extreme error suite
function extraInfo(e){
//e optional
if(!e)e = true;
//add an extra debug info, such as navigator or current URL
return ' currentURL: '+ document.URL +
'\n userAgent: ' + navigator.userAgent +
'\n platform: ' + navigator.platform +
'\n userid: ' + localStorage.userid +
'\n language: ' + navigator.langauge +
'\n cookies?: ' + navigator.cookiesEnabled;
}
Xe.error = function(e){
console.error(e); //maintain original functionality
mailError('Xe err: ' + e + extraInfo() );
}
Xe.warn = function(e){
console.warn(e);
mailError('Xe warn: ' + e + extraInfo() );
}
Xe.log = function(e){
console.log(e);
mailError('Xe log: ' + e + extraInfo() );
}
As a last ditch, you can continually attempt to execute a chunk of code until it executes without errors. This is "2" below.
2:group code in large chunks and attempting to re-execute x seconds later after catching an error, or continue to next chunk of code
//defExe = DEFinitely EXEcute this code
//functionArg, reference to a function holding a large chunk of code
//seconds, timeout in milliseconds to re-attempt error free execution of this function
function defExe(functionArg, seconds) {
//seconds is optional
if (!seconds)seconds = 300;
try {
functionArg();
} catch(e) {
//mail the error plus extra info
mailError('caught ' + e + ' attempting to re-execute ' + functionArg.name + ' in ' + seconds + ' milliseconds');
//re-attempt to execute this code
setTimeout(function(){
defExe(functionArg, seconds);
}, seconds);
}
}
this it is then used like
//array to group function chunks
var fn = [ ];
fn[1] = function (){
//a large chunk of javascript
}
defExe(fn[1]);
fn[2] = function(){
//another chunk of your program
}
defExe(fn[2]);
#2 Summary: Group code in functions and run in try-catch block, repeating if an errors are caught
Upvotes: 40
Views: 89890
Reputation: 41
Sorry but try/catch will catch only code errors, never load error (if a file is missing or something that).
window.onerror / $(window).error is definitely the best solution.
Upvotes: 4
Reputation: 124
You can try also
Try...Catch Statement
try
{
//Run your code here
}
catch(err)
{
//Handle the errors here
}
Upvotes: -1
Reputation: 1744
I have mine working with window.onerror and it doesn't stop my javascript:
window.onerror = function(error, url, line) {
controller.sendLog({acc:'error', data:'ERR:'+error+' URL:'+url+' L:'+line});
};
Note that controller.sendLog is a function that sends this data to a logging php.
Can be because you're causing some javascript error inside that function?
Upvotes: 65
Reputation: 7866
When an exception is raised in most languages, execution of the current command stack is going to be stopped. So your global window.onerror approach works, but doesn't continue to execute code after a failure. I'm curious why you would expect a retry to work in the case that the original call fails? Maybe there's another way to optimize your application to avoid this.
One of the things I like to do is wrap any of my code in window.onerror function in a try catch block. In the catch statement (last resort) I will generally use an alert of some sort, just in case something goes catastrophically wrong. The idea here is that you don't want your error handling for the page to EVER end up causing another error to be launched.
Upvotes: 2