Devin Rhode
Devin Rhode

Reputation: 25287

Get all javascript errors on page/javascript error handling

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

Answers (4)

Pascal Trouvin
Pascal Trouvin

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

The Fire TITAN
The Fire TITAN

Reputation: 124

You can try also

Try...Catch Statement

try  
{  
  //Run your code here
}
catch(err)
{
  //Handle the errors here
}

Upvotes: -1

Sergi Ramón
Sergi Ramón

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

Justin Beckwith
Justin Beckwith

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

Related Questions