Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get notified when JS breaks?

Tags:

javascript

I have configured PHP to send me mails whenever there is an error. I would like to do the same with Javascript.

Also given the fact that this will be client side it is open to abuse.

What are good ways to get notified by mail when JS breaks in a web application?

Update:

Just to give some perspective, i usually load several js files including libraries (most of the time jQuery).

like image 616
amosrivera Avatar asked Aug 08 '11 16:08

amosrivera


2 Answers

You can listen to the global onError event.

Note that you need to make sure it doesn't loop infinitely when it raises an error.

<script type="text/javascript">
var handlingError = false;

window.onerror = function() {
   if(handlingError) return;
   handlingError = true;

   // process error

   handlingError = false;
};
</script>
like image 75
David Hedlund Avatar answered Sep 20 '22 16:09

David Hedlund


The code below relies on the global onError event, it does not require any external library and will work in any browser.

You should load it before any other script and make sure you have a server-side jserrorlogger.php script that picks up the error.

The code includes a very simple self-limiting mechanism: it will stop sending errors to the server after the 10th error. This comes in handy if your code gets stuck in a loop generating zillions of errors.

To avoid abuse you should include a similar self-limiting mechanism in your PHP code, for example by:

  1. saving and updating a session variable with the error count and stop sending emails after X errors per session (while still writing them all down in your logs)
  2. saving and updating a global variable with the errors-per-minute and stop sending emails when the threshold is exceeded
  3. allowing only requests coming from authenticated users (applies only if your application requires authentication)
  4. you name it :)

Note that to better trace javascript errors you should wrap your relevant code in try/catch blocks and possibly use the printstacktrace function found here:

https://github.com/eriwen/javascript-stacktrace

<script type="text/javascript">
  var globalOnError = (function() {
    var logErrorCount = 0;
    return function(err, url, line) {
      logErrorCount++;
      if (logErrorCount < 10) {
        var msg = "";
        if (typeof(err) === "object") { 
          if (err.message) {
            // Extract data from webkit ErrorEvent object
            url = err.filename;
            line = err.lineno;
            err = err.message;
          } else {
            // Handle strange cases where err is an object but not an ErrorEvent
            buf = "";
            for (var name in err) {
              if (err.hasOwnProperty(name)) {
                buf += name + "=" + err[name] + "&";
              }
            }
            err = "(url encoded object): " + buf;
          }
        }
        msg = "Unhandled exception ["+err+"] at line ["+line+"] url ["+url+"]";
        var sc = document.createElement('script'); sc.type = 'text/javascript';
        sc.src = 'jserrorlogger.php?msg='+encodeURIComponent(msg.substring(0, Math.min(800, msg.length)));
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(sc, s);
      }
      return false;
    }
  })();
  window.onerror = globalOnError;
</script>
like image 35
Sergio Avatar answered Sep 18 '22 16:09

Sergio