Posts RSS

crash coherency

Programs, sysadmining, cybersecurity

Javascript Automatic Error Reporting

by agentme at

Websites often have to work across many different browsers and devices, but we can't always test our code on all platforms. CSS quirks can cause some visual oddities, but differences in browser Javascript APIs can break a site's interactivity. You can try to write close to your knowledge of the standards and hope your users report their issues. Then six months later someone finally lets you know that Feature X is completely broken anyway in IE/Android 2.x/their Nintendo DS's browser, and they thought you knew about it already.

You test it yourself, and it turns out that you called a non-standard method on some object during the page load event, throwing an exception, and your entire script dies. You fix it by checking for the presence of the method first or by using a try/catch block. That problem is solved. And next week, someone lets you know that there's been another unhandled exception for the last eight months when the site is viewed through Steam's overlay browser.

What if you wrapped all of your code in a try/catch block, and sent every otherwise uncaught exception with some browser data to your server in a background AJAX request? You could keep a log of these exceptions on your server. It'd be a bit similar in concept to Windows' error reporting tool, except invisible to the user and automatic. There's no reason to not do this automatically in a website. (Desktop applications should probably err on the side of privacy though.)

Having a giant try block might look a bit ugly in the code and require some changes, but thankfully browsers give us an easier way to accomplish this. Just set a handler on window.onerror. The function will be called every time an exception isn't caught. It's also handy to have a utility function that will send a report for a caught error for in places you already have other handling.

The above code is free for any use without restriction. It depends on jQuery for AJAX, it automatically retries sending after timeouts, and it has some crude rate-limiting which is very handy when it turns out that your code causes a hundred unhandled exceptions every second on some odd platform.

Note that not all browsers include the 4th and 5th arguments to the window.onerror function. Some browsers include a stack attribute on Error objects, but if the fifth argument to onerror isn't given, you won't see that. If you minify your javascript, make sure it doesn't put it all on one line, or else browsers that lack column information will give useless reports.

The source code for the server end is trivial. On one project, I just have a PHP script that verifies it received valid JSON-encoded data, and then appends it to a log file.

Now you can check your server logs occasionally to see if there are any unhandled exceptions, and you can often pinpoint issues in specific browsers without even having to test with that browser yourself (though you'll probably want to at some point anyway)!

If a user ever reports mysterious issues on your site, you can pull up your server's log of exceptions, grep for the user's IP address, and see if there's something you missed from that user. It's great to be able to tell a user that you've pinpointed the cause of their issue the moment after they've mentioned it to you.

As an extra note, don't forget about server-side errors, including user errors. You know that error message you send to a user when they try to post a comment that's too long? Or that error that's triggered when their POST body is missing some vital field? Log it somewhere, because one day, someone is going to try to use your site with a uniquely broken browser that does something ridiculous, and it's going to drive you crazy until you notice that the issue really is just because their browser can't actually handle a POST request.

No comments yet.
Post a comment!