Saturday 17 December 2011

Control Error Posting Better

One constant problem with Errorception is managing the huge influx of errors, because Errorception does such a good job of recording errors. (You see how I sneaked that last bit in?) We've always had automatic "muting" of possibly uninteresting errors. Some time ago, we started automatic marking bugs as duplicates, which brought down the number of errors that you had to deal with drastically.

Today, we've launched yet another feature to help reduce the number of errors you need to care about. You can find this under "Settings > Posting errors".

Allowed domains

You can now specify a white-list of domains from which you want to record errors. So, if you whitelist www.mydomain.com, errors from localhost will not be recorded. You can specify as many domains as you want - just comma-separate them. This also helps safeguard you from people who might have stolen your tracking code and are spamming you.

Ignored scripts

You can specify a black-list of paths for script files. If errors occur in script files matching this file path, such errors are not recorded. This means that you can now block your third-party scripts for example from posting errors to Errorception. So, no more do you need to get errors from the Facebook Like button, or from your Customer Support chat widget.

Also, as a bonus, if the errors are ignored due to any of the reasons above, such errors will not count against your rate limit. This gives you more room every day to record the errors you really care about.

Lesser errors = happier developer, right?

Tuesday 13 December 2011

Call Stacks in IE

Over the weekend I rolled out a build that provided call stacks for certain errors, under certain conditions. You only get a call stack if:
  • The error occurs in Internet Explorer,
  • The error happens after page load

I must admit, because of these conditions I was unsure how useful the feature will be. But after having it run for some time now, it looks awesome!

If we were able to capture the call stack of an error, it is highlighted in the errors listing.


The call stack is shown in the error details page for the error.


How it works


One interesting behaviour of IE is that when window.onerror is called, it doesn't actually destroy the call stack — in fact, the window.onerror function call is placed on the top of the currently executing stack. This is different from how all other browsers behave. We exploit this behaviour in IE.

However, IE doesn't give you a nicely formatted stack trace. In fact, there's no explicit way to get the call stack at all. However, IE does give you a meaningful arguments.callee.caller, which is used here. We then recursively walk the call stack using arguments.callee.caller.caller etc. to build individual stack frames of the error. We do this for 10 stack frames and stop there, just in case the call stack is for a recursive function.

arguments.callee?


arguments.callee refers to the currently executing function. It's a way for a function to know itself, if you will. In JavaScript, since every function is also an object, the function has it's own properties as well. One such property of a function is its .caller, which is a reference to the function that called it. In other words, it's a reference to the function one stack frame below itself.

In the case of window.onerror, arguments.callee will refer to the window.onerror handler itself, since it points to itself. Once we have a handle to our own function, we can then access properties of our function, as described above.

There's one caveat though. Only IE retains a meaningful arguments.callee.caller. In all other browsers, this value is null. That's because all other browsers destroy the call stack before calling window.onerror. IE retains the call stack. So, since we have a call stack in IE, we can now recursively call .caller for each function in the stack to know the previous function in the stack.

Why after page load?


As I've mentioned several times before, Errorception will always maintain a zero performance cost. I wouldn't use a error reporting system that would cause page load delays for every single user. To ensure that the performance cost is zero, Errorception introduces it's script after page load. This doesn't mean that we don't catch errors from before page load, of course. We do. But we only process them once our script has loaded.

Because of this loading pattern, we won't have access to call stacks from before page load. arguments.callee.caller will always point to null since the stack has already unrolled. This is why we cannot generate call stacks before page load, even though we have all other error details.

But that sucks!


Not really, if you think about it. While it would be awesome if we could get call stacks from before page load as well, these errors are really easy to replicate. That's because the error happens in such a small and predictable time interval that it's easy to recreate it locally. The error happens between when the page started loading and when page load was fired - usually within a couple of seconds, maybe before any user interaction has even occurred.

Caveats


In a lot of cases, the call stack consists of anonymous functions, which isn't very descriptive. I would ask you to rewrite your code using named anonymous functions, but we all know that no one's going to do that. I'm still on the lookout for a decent way to solve this. If you have any suggestions, I'm all ears.

Saturday 10 December 2011

MOAR Stats!

Just released a build that takes all your error data and makes pretty little pie charts out of it. Who doesn't like pie charts, right?

To access this data, hover over your projects menu at the top right when you log in, and click on the "See more stats" link in the drop-down.


Monday 5 December 2011

Paid plans - ACTIVATE!

I've just opened up sign up for the paid plans. The paid plans had been announced some time ago, and I was waiting for the paperwork to go through for launch.

The paid plans are available on the pricing page. As always, your feedback is always welcome.