Logging JavaScript errors

In one of my latest posts I talked about using Monolog to remotely log stuff on New Relic: getting a bit deeper on log management systems, here’s how we managed to report JavaScript errors on our logs.

A note on JavaScript errors

It may not sound obvious, but errors, in JavaScript, can be pretty nasty, since it’s an – almost completely1 – client-dependent technology that can react differently to your code based on the client’s platform.

Cross-browser testing may not always be performed that accurately, so you should definitely start tracking JS error that may happen of different clients.

The concept

This is totally not an idea of mine: it comes from a pretty smart blog post which illustrates the main concept: when a JS error is encountered, you trigger an HTTP request to a URL that collect the data transmitted within that request and logs it with server-side code.

How to trigger JS error reporting
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
window.MaximumErrorCount = 5;

window.onerror = function(errorMsg, file, lineNumber) {
  window.errorCount || (window.errorCount = 0);

  if (window.errorCount <= window.MaximumErrorCount) {
    jQuery.post('/jsError/', {
        errorMessage:   errorMsg,
        file:           file,
        url:           window.location.href,
        lineNumber:     lineNumber,
        ua:             navigator.userAgent
    });
  }
}

So, at the end, you only need to add some basic server-side code to handle the reported data:

How to handle reported informations
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php

class ErrorController extends Controller
{
  const MESSAGE_LOG_JAVASCRIPT = 'A javascript error "%s" has been encountered at the URL %s on file %s:%s by an agent of type %s';

  public function logJavaScriptAction($postData)
  {
      $logMessage = sprintf(
          self::MESSAGE_LOG_JAVASCRIPT,
          $postData['errorMessage'],
          $postData['url'],
          $postData['file'],
          $postData['lineNumber'],
          $postData['ua']
      );

      $this->getLogger()->addError($logMessage);
  }
}

You may want to write some additional code to only report errors that you should really fix: based on the user-agent, for example, you can ignore errors triggered on MSIE 7.0/MSIE 6.0.

All in all…

This has been a great solution for us, since we could easily keep track of JS code which was causing errors due to:

Notes
  1. NodeJS

In the mood for some more reading?

...or check the archives.