Saturday, September 01, 2012

The Dave Super Duper AJAX Exception Handler

This is a write up I did for a client when they were having a hard time troubleshooting an ajax application. I think this info would be generally useful so I thought i would throw it up on my blog.


Problem

We are observing intermittent errors through the jmeter tests and also through interactive tests. The errors are in a format such that:

  1. The AJAX client cannot respond appropriately to the error.
  2. They provide no useful information (to the client programmer or the user).
  3. Load test failures are hard to interpret
  4. Its difficult or impossible for the ajax client to know for certain if there was an error.

Cause

Server-side error handlers that log a message but do not inform the caller that anything went wrong.

Solution

All JSON calls should return one of two things:
  1. a valid response or
  2. a deliberate json error message, one that that the ajax client can make use of (i.e. try again, inform the user, send an email to cpd, etc). Also, it should aid in debugging.

Unintended AJAX Responses
As it currently stands (in the app we are troubleshooting) the JSON calls sometime return a third thing: an indeterminate, unintended response. A response that was not deliberate but rather accidental. This type of response cannot be handled appropriately by the AJAX client.

The unintended ajax responses that we have observed (using jmeter, interactively with firebug and looking at the code) include:

  1. ajax calls returning html
  2. ajax calls returning status code 200 and no response body (html, json or otherwise)
  3. unintended json: an error occurs server-side, and is only half handled: i.e. its logged to the server logs, but then a half-completed json response is returned to the client.

All three of these make it hard for the the ajax client to respond to errors. They make it hard for the ajax client to even know if there was an error. Its not enough to just log errors, they must be handled as well.

The Ultimate Awesome AJAX error handler

This secret tip will save you 1000s of hours of requesting and dealing with log files, especially when used in conjunction Firebug-like tools or with jmeter. This is one of the most useful tips ever, especially in this client's environment.

Also, its very difficult to associate a message in the error log with the bug detected by a UAT tester. It's even harder to connect an error in a load test with a line in the error log. Even if everyone has perfectly synchronized clocks.

So here is a generic version of the error handler (for use with Spring):

} catch (Exception e) {
model.addObject("errorCode", e.getClass().getSimpleName());
model.addObject("errorMessage", e.getMessage());        model.addObject("stackTrace", Util.serializeStackTrace(e));
}


If you add the error handling changes that I suggested in the last email, UAT testers and keynote test scripts will instantly know "it was a cmllink" problem or "it was a dod problem", without having to:

  • request log files
  • wait for log files
  • spend hours sifting through megabytes of irrelevant information in the log files
  • spend hours trying to correlate one of the million log messages to what happened in the browser.

The key point is that the actual error (the relevant error, the one that happened 8 layers down in the app) must bubble to the top level error handler and get send back to the client in a format the client can process.