I’ve had this post in my submission bin for a while but a question of the digital point forums today prompted me to dig it out… First of all, what is the difference between a javascript exception and a javascript error? Well, my view on this is simplistic: an exception IS an error of a runtime nature that can be handled, whereas an error is typically to do with syntax and can’t be ‘caught’.
So why would we care of exception errors anyway?
Whilst programmers take every possible measure to release compliant and bug-free code for all possible browsers, the sad truth is that–for ajax-rich applications–no amount of testing can ensure things won’t break for somebody. There always will be the ‘daft’ people, their quirky old browsers (IE6, anyone?), odd plug-ins, proxies / anti-virus software, leap years and so forth–somehow managing to trigger unexpected javascript exceptions. The more traffic you get, the better the chances are for somebody to stumble upon such difficulties. What you don’t always get is people phoning up to tell you about it. Not unless it’s something critical – like the inability to add an item to a shopping basket or failure to checkout. And let me tell you, your customer services won’t be able to get any meaningful debug information.
A practical example?
Recently I got a report of a customer that was unable to checkout and for whom the ‘checkout’ button did nothing. The button itself had an onclick event assigned to it within the mooTools domready function… Surprisingly, it turned out the domready just consistently fired up earlier than expected for him, with the checkout.gif image just not being a part of the DOM at the time of the event assignment. This got me worried and made me want to try and discover other such potential deterrents to people’s browsing experience.
The solution is closer when you know your problem areas…
I created a javascript exception trapping handler and placed it around what was perceived to be the ‘dangerous / unsafe’ portions of the checkout code. The handler itself was set to use XHR (ajax) to send me the exception data via email, alongside of whatever additional data the PHP script was able to grab (browser, user info, basket contents and so forth). The results were… astonishing. This quirk was happening a fair bit more than we would have liked (1 in 30 customers). We also found out that our promo codes buttons were also being affected… The flaw in the mooTools 1.11 domready code aside, how did we fix it? By not assigning events until all the elements were available, by using load as opposed to domready for IE users and so forth.
Here is the refactored code for mootools 1.2+ instead:
var errorHandler = function(dbug) { // trap errors and send via ajax to a script that logs them new Request({ url: "/errorTrap.php", data: dbug, onComplete: function() { $("errorOutput").set("html", this.response.text); } // comment this function out out and the comma on the line above. data will arrive via $_POST. }).send(); return true; }; // end errorHandler $("makeException").addEvent("click", function(e) { new Event(e).stop(); try { duffColours[2] = 0; } catch(er) { errorHandler(er); // install it. } });
And here is an example of the errorTrap.php contents, I’d advise you to do data washing/escaping as well:
<?PHP $body = "ERROR DETAILS FOLLOW:\n\n"; foreach($_REQUEST as $key => $value) { $body .= "$key: " . str_replace('"', '\"', $value) . "\n"; } $body .= "\n----------------------------------------------------\nServer variables:\n\n"; foreach($_SERVER as $key => $value) { $body .= "$key: " . mysql_escape_string($value) . "\n"; } mail("your@email.com", "JS exception on {$_SERVER['HTTP_REFERER']}", $body); ?>
To create an exception, click here – it will send it to a file called errorTrap.php, which iterates the $_GET and $_SERVER variables before dispatching me the email
GitHub flavoured markdown enabled.