Designing mobile APIs – error handling

Jonah Williams ·

While designing an api I need to provide reliable error responses to both protocol and application level errors. Here I’ll consider any error response generated outside our application stack to be a protocol error while those errors returned from my application’s codebase are classified as application level errors. On a recent project I started to conflate these two categories which would have made the client implementation unnecessarily difficult if my pair had not intervened.

Before a request ever reaches my application it might timeout, it might be required to provide authentication, be redirected, hit a 404 “not found” response if my site is down for maintenance, or encounter a 5xx server error. These protocol level errors are handled well by HTTP status codes in the response header. In any of these cases there’s no need for the client to attempt to parse the response body.

Once a request reaches my Rack/Rails stack it might still result in an error response if no matching route exists or if it fails validation. Some of these application level errors might map to HTTP status codes but not all of them. For example in the case of validation errors I want to return relevant messages to the client. In these cases I want to send a 200 response code to indicate that the response body can be expected to be well formatted. The client can then attempt to parse the response as JSON, identify that there was a validation error, and notify the user appropriately.

In a recent project my api responses looked something like this:


{
'error' : {
'type : "AStringDenotingTheErrorType",
'message' : "An error message appropriate for display to the user."
}
'data' : {
"attribute": value,
...
}
}

Mobile clients who maintain an offline cache of data might encounter validation errors as a result of being out of date with the server. I found it helpful to include an up to date representation of the model which failed validation in the error response. Much like rendering a form with validation errors, returning a model or other data along with a set of validation errors allows the client to make sure they are not submitting an out of date version of the resource.

For instance on an application which cached forms it received via an API submitting an old version of a form might result in a validation error. By returning the latest copy of the form with that validation error the client had an opportunity to update its cache and present the correct form the the user to make corrections and fill out new required fields.

A well designed API will communicate both application and protocol errors clearly to the client. It supplies the client with an appropriate level of information to correct errors when possible and saves the client from needing to guess what might have gone wrong with a failed request.