2005-12-19

Graceful JSON degradation

Let's assume you are publishing a JSONP feed, or indeed any kind of JSON feed -- such as the Del.icio.us JSON feeds for posted URLs, or lists of tags, and so on. All of a sudden, your service goes down. These things happen to all of us; be prepared for it. Usually, it is good service to show a user friendly error message that tells users what has happened -- we apologize for the outage, read more about it here, that sort of thing.

For JSON feeds, it is not. Remember, these messages are intended for human consumption, JSON is not. If you provide an HTML encoded message for the visitor, it will most certainly be malformed JSON, and your users may, at best, get a very unfriendly error message in their javascript consoles. Assuming you are providing a JSONP feed and the calling part sent out a request that should run the callback got_data, which expects a single array parameter of something, and you have not formally specified an error API for handling these circumstances, what you should send back to the client is a simple got_data([]) -- nothing more, nothing less.

If you are the Del.icio.us page for fetching posts, you provide a similar JSON null response:
if(typeof(Delicious) == 'undefined') Delicious = {};
Delicious.posts = [];

...and nothing bad will happen.

The above example is of course in lieu of the recent Del.icio.us outage and the featured error in my case was "XML tag mismatch: </body>", when running Mozilla 1.5. When running Internet Explorer, it's "Delicious is undefined." instead. Neither very informative, and both also yielding somewhat broken web pages (as my blog uses the Del.icio.us JSON feeds for tags visualization and browse posts by topic features).

The curious reader might wonder why the Mozilla error message came out quite like that. Isn't the Delicious object used later in the page just as undefined for Mozilla as it is for Internet explorer?

Well, it is, in fact, but before that, the presumed-javascript contents of the Del.icio.us page we requested is parsed, as javascript. And with the coming of E4X (ECMAScript for XML), which Mozilla 1.5 supports, it very nearly is valid javascript. Had it been a properly balanced XML page, it would actually have parsed as valid javascript, and rendered the same error IE saw when later page features prodded at the Delicious object (liberally assuming it was there -- I could of course have been more sceptical myself and tested for its exsistance first with a simple if( typeof Delicious == 'object' ){...} and been safe).

But it wasn't; there was an unterminated <p> tag there, and we got the puzzling bit about badly balanced XML instead.

Lessons learned? Degrade JSON nicely. A balanced XML diet is a healthy thing.
blog comments powered by Disqus