A naïve attempt at getting started
Getting up and running with a system to log browser errors is rather painless in and of itself. You can pick from the existing providers, or you could roll your own. All of the providers simply hook into
window.onerror and send that information to their backend in order to render their pretty graphs. It's typically just a question of adding the service's
<script> tag to your page (they'll have something for you to copy/paste) and you'll be logging in no time. Unfortunately, you'll also notice that you'll have no stack traces and most of your errors will simply report themselves as
Script Errors with no line number or filename. Not entirely useless, but nearly... let's see if we can fix it.
Well, of course it's a
Script Errors. For security purposes, browsers will not report errors for scripts from a different origin; they will simply report a
ScriptError instead of divulging the true nature of the exception (e.g. ReferenceError). But there's an exception to this policy if you load the script using CORS. In a nutshell, Cross-Origin resource sharing (or CORS) is a spec that lets your scripts (or other assets) sidestep the Same-Origin-Policy. For us, the CORS spec boils down to a request with a header
Origin: http[s]://mysite.com and the response script with a header
Access-Control-Allow-Origin: http[s]://mysite.com or
Access-Control-Allow-Origin: *. Under these circumstances the browser will provide us with the true error message in
Getting set up with CORS
In the simplest case, all we have to do is add the
crossorigin attribute to our remote
<script>s to enable the request header and configure your server to enable the response header. There are, of course, caveats:
- Unfortunately, as of September 2013, this doesn't work in Chrome but it should be released in version 30 or 31. IE does not support the attribute and we don't know if/when it will.
- If you are getting your script from some other source that you don't control, it's possible that the provider has not enabled CORS at all. If you cannot get CORS to work at all, there is not much you can do short of downloading and hosting the content yourself (although please also poke them about enabling CORS).
So what can we do?
There is no good solution just yet but we have a few options:
- Take what onerror gives us and run with it. It's really not that bad. We can tell a lot from having just the file, error, and line number.
- Try/catch all the things! Theoretically, we could wrap every function call in a try/catch and we'd have an error object in the catch block. This is bad; please don't try. You'll have a particularly hard time with asynchronous callbacks anyways. You can put reasonable try/catches where things could really go wrong though.
- Use a front-end web framework. Some front-end JS frameworks have execution contexts that can capture exceptions and give us a real error object (with a stack!). For example, Angular has $exceptionHandler and Ember has a real onerror function.
- A bit of everything. When the errors are not in Angular/Ember (or if you aren't using a front-end framework at all) and the onerror message is not clear enough, throw some try/catches around to weed out the issues.
- Wait for it... The ecosystem is not quite setup for painless JS error logging. In a year or two, browsers will have better onerror support and both browsers and CDN providers will have better CORS support.