Tracking Down an Unexpected jQuery Error
I don't like silent errors. I don't like uncaught errors. So, to me, this is a bug. That said, I'll readily admit that my assessment is more than arguable. There may be very good reasons for doing it this way, but at the very least it's a scenario that may play out for others and confused me for hours until I finally tracked down what was happening. For that reason, it made sense to write it down.
The Scenario
I have a simple, stupid user interface that allows users to enter a set of criteria and then run one or more reports. The reports are executed by an AJaX request and all return a number or a small set of numbers. To do so, however, a huge amount of data has to be queried. When I say huge, I mean MySQL is querying well over a hundred million records. Needless to say, the reports can run for a while depending on the criteria selected.
The Code
I'm using the jQuery JavaScript library for this project. The details are unimportant, but when a report is executed from the UI, the following code is called:
The Problem
On a number of test executions - but not all - the AJaX call was returning an error. More to the point, it was returning a syntax error. It wasn't in my code because some calls were working. Eventually, I realized that it was the large (read: long running) reports that were erroring, but I couldn't figure out why I was getting a syntax error rather than a memory or timeout error of some sort.
What I found was really two problems. One mine and one jQuery's (in my opinion). After a bit more testing I tracked down a pattern and after digging through the jQuery code I finally found the source of the error message.
The first problem was that the web server was timing out my long-running request. That makes sense. By monitoring Firebug, I began to notice that all of the requests that were throwing errors were doing so after ~5 minutes. The error message I was receiving gave no indication that this was the problem, though, and, more importantly, lead me in a different direction all together (i.e. to my code).
Which leads us to the second problem. When evaluating the AJaX response, in this case, a JSON value, jQuery doesn't apply any error handling. It's expecting JSON and doesn't account for any response that can't be evaluated as JSON. When the response is returned, it is simply evaluated. Period. In my case, because of the timeout, the value was null. Not a JSON value. It was the eval() statement that was throwing the syntax error.
The Solution
First, of course, I had to increase Apache's request timeout. Since this is an internal UI for non-critical reporting, I just made it unlimited. Not a recommended setting for most uses, of course, but suitable for this particular effort.
Since the solution to the first problem prevented the second from occurring, I decided not to make any changes to the jQuery library (I'm loathe to do that with distributed code, anyway, in order to maintain an easy upgrade path), but I would ask the jQuery developers to consider at least wrapping that eval() call in a try/catch block to better facilitate debugging efforts. A simple statement that the JSON value returned by my AJaX call was invalid would have saved me a lot of time and effort.




Loading....