XING Devblog

How to log JavaScript errors

| Posted by

As with most web 2.0 platforms, a large part of the platform interaction on XING is handled via JavaScript. In total, 25,000 lines of code render dynamic content on our platform. Dragging and dropping the boxes of your start page, editing settings in your profile, a live search selecting your contacts when you type a new message – AJAX is just about everywhere.

The challenge: debugging user-sided script

Although this has many advantages, it’s also quite a challenge. In web 1.0 times, quality assurance consisted of ensuring a consistent design of the mostly static HTML on the user’s browser and debugging the code meant going through the CGI scripts running on your server – with known hardware, software and preferences.

A platform relying heavily on JavaScript changes this. The scripts run on many different browsers in many different versions whose JavaScript implementation may vary a lot. My colleague Ingo Chao wrote about the problem of degradation without grace. Now, where a non-standard interpretation of CSS might merely lead to an broken design, a script waiting for an event not set in the browser could lead to a drastically reduced functionality of some features. Plus, engineers are (despite to all rumors:) humans and thus make mistakes.

Compiling an error report

So how do we log JavaScript errors? Besides the internal testing on several browsers in different versions, we actually record all error messages that occur on the user’s side.

To do this, we use the event handler window.onerror:

window.onerror = function(errorMessage, url, line) {
  var loggerUrl = "https://www.xing.com/js/logger";
  var parameters = "?description=" + escape(errorMessage)
      + "&url=" + escape(url)
      + "&line=" + escape(line)
      + "&parent_url=" + escape(document.location.href)
      + "&user_agent=" + escape(navigator.userAgent);
 
  /** Send error to server */
  new Image().src = loggerUrl + parameters;
};

So, whenever an error occurs, we record the user’s browser, the URL of both the script file and the HTML container, the code line and the error message in a log file. Private data such as the user id, the company, a possible premium membership or anything else that falls into that category is not transmitted. We record every error, from division by zero (unless you are Chuck Norris) to infinite loops. The only errors left out are those appearing in Internet Explorer 5.5 and earlier.

Based on the above mentioned URL and error message, the server then builds a hash as a unique id for this error. The catalogized errors are counted and sorted in descending order.

Error 1: illegal character

A cronjob initiates that an error report showing all messages and their frequency of occurence to the frontend engineering department so the team knows where it needs to focus. This way, we receive a list of errors that are often not even perceived by the end user, and we also know which errors are most pressing.

m4s0n501

About the author


14 thoughts on “How to log JavaScript errors

  1. Hi Christopher,
    the concept of this logging function is very clever.
    May I use it for my debugging projects?
    By the way: the variable ‘url’ seems to be defined twice.
    PC’L

  2. One question remains: how do you determine the line number? I can only think of hard coding, but that would be stupid, because it’s hard to maintain.

    And shouldn’t you use encodeURIComponent instead of escape? (OK that was a second question, but since it’s a rhetorical one you could count that as a statement.)

  3. Hi Matthias,

    the line numer is given by the browser. There’s no need to determine it manually.
    Regarding your second question:
    Thanks for the hint. We used “escape” in the beginning to track errors in old browsers that doesn’t support encodeURIComponent. This became obsolete after we decided to stop logging errors that were happening in old user agents.

    Cheers,
    Christopher

  4. Hi Bastian,

    we have set a limit of errors logged each day and our daily report only contains errors that occured more than a given number.

    Cheers,
    Christopher

  5. Hi Christopher,

    How do you handle minified and obfuscated scripts? Would the line number still provide you informative / decodable information?

    Thanks,

    Fortune

  6. Hi Fortune,

    the line number in minified scripts is indeed a downside.
    As we minify all our assets, we cant use the line number at all for debugging purposes.

    Do you have an idea how do deal with this problem ?

    Björn

  7. Logging JavaScript errors is amazingly hard to do right. I’ve spend hundreds of hours cracking that nut. And the result is my free service for logging JavaScript errors called Muscula.

    I’ve actually also tried my hand at cracking the nut of getting call stacks on those errors. And succeeded in getting call stacks for at least some of the errors.

  8. We built a specialized tool for logging errors and custom events on frontend – JSLogger. It’s pretty nasty to capture this logs in all common browsers and mobile devices. It took a while until we made it to work properly. There is a NodeJS library for it, so you can use JSLogger from backend as well.

  9. Pingback: Logging front-end errors with your usual CodeIgniter logging. |

  10. JSNLog would be another alternative. It’s a free library (1.5kb) that sends log data to your server. It also lets you suppresses duplicates, batch log data, and lots more to prevent your server from getting overwelmed.

    Depending on your platform, it also includes a server side component to receive log data from the browser and log it on the browser. This also lets you configure your client side loggers via a server side config file.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>