Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a conventional way of returning error statuses from JSON web services?

I have a .NET .ashx handler, which receives a jQuery AJAX post, formats a web service request to a third-party service and consumes the result. On success, it instantiates an anonymous object with the relevant information and formats a JSON response string.

In the event of a web service error, I do the following:

context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
context.Response.StatusDescription = wsResult.ErrorCode;

This makes both the status code and description easily accessible to the jQuery AJAX error callback; however, the way I have implemented this is quite arbitrary.

After doing some reading around, I can't find a conclusive answer to the following question: Is there an accepted, universal convention (or - even - specification) for returning error states to JSON-based AJAX calls, which allows any consumer to know what to expect, or is this as arbitrary as a return type for any other function call?

So, is this a perfectly acceptable way of returning an error status to the AJAX caller, or is there a "proper" way of formatting a JSON error response?

like image 906
Ant P Avatar asked Jun 25 '13 09:06

Ant P


3 Answers

As others have said, there's no universal convention. The REST "community" is still in the process of finding some consensus in matters like these - a consensus may never be found. Just to give a few examples:

Status code

By default ServiceStack.NET, a widely used C# REST library web service framework, returns the object (or empty response) with a status code, e.g.:

201 Created

Or:

200 OK

In the case of a validation error (e.g. an ArgumentException), it may do e.g.:

400 Bad Request

And here's already the first point where things start to vary. Some people like the 400 status code for things like validation errors - others don't, since 400 really indicates malformed syntax in the request format itself.

Some prefer 422 Unprocessable Entity for validation errors, a WebDAV extension to the HTTP protocol, but still perfectly acceptable technically.

Others think you should simply take one of the error status codes unused in the HTTP protocol, e.g. 461. Twitter have done that with (among others) 420 Enhance Your Calm to notify a client that they're now being rate limited - even if there's an (on the surface) acceptable (and recommended) status code 429 Too Many Requests for that purpose already.

Etc. It's all a matter of philosophy.

As for 500 Internal Server Error, the same applies - some think it's perfectly fine for all kinds of error responses, others think that the 5xx errors should only be returned on exceptions (in the real sense - i.e., exceptional errors). If the error is truly exceptional, you mostly wouldn't want to take the chance and pass on any actual exception info, which may reveal too much about your server.

Leading us to what (if anything) to return in the JSON result? Same thing...

Response

200 OK may be quite enough for responding to e.g. a request to delete a resource, if no error occurred. In the same way, 404 Not Found is enough to tell the client that the requested deletion couldn't be performed because the entity to delete wasn't found. In other cases you may require more than that.

Some people think you should include as much of the needed info as possible in the response headers, often having an empty response with only headers. For example, on a creation, return 201 Created and put the created entity's ID (as a resource URI) in Content-Location. No response content needed.

I personally think that if you're making a public API, it's a good idea to return both appropriate headers and content, even if the content is somewhat redundant. I.e.:

HTTP/1.1 404 Not found
Content-Type: application/json; charset=utf-8
...

{
   'Success': false,
   'Message': 'The user Mr. Gone wasn't found.'
}

(I don't actually include the Success property, but I might want to, depending on my frame of mind when designing the API).

When running in DEBUG mode, I also include a string representation of the internal service call - e.g. 'Request': 'GetUser { id: 5 }', a timestamp, and the stack trace. It's all a matter of convenience, though. It's easy enough to code a client with proper user friendly error messages simply based on 404 Not found. Some other errors (e.g. validation) may need more context, though. For example:

HTTP/1.1 422 Validation Error
Content-Type: application/json; charset=utf-8
...

{
   'Success': false,
   'Message': 'The request had validation errors.',
   'Errors':
   {
       'UserName': 'The user name must be provided.',
       'Email': 'The email address is already in use.'
   }
}

ServiceStack.NET does something like this by default, but with slightly different properties and content. Microsoft's own Web API framework does something similar. The JSend spec linked in the related question is another variation.

And so on.

In short, no, there isn't any universal convention - not yet, at least. Lots of people (putting more thought into it than I) are working on it. But still, there may never be. And your method is perfectly acceptable.

(Yes, this was very lengthy - mostly because I've been searching around for the same kind of "universal convention" for a while).

For more on status codes, this is an excellent article (too long to quote here)

like image 189
JimmiTh Avatar answered Oct 27 '22 04:10

JimmiTh


No, there is not any single major standard out there, although this might be nice. It might be useful if you are making yourself a standard to include success and details, but it depends on exactly how you are using it. I think the big advantage is when you implement a standard at least across all of your own code for consistency, e.g. http://ricardocovo.com/2012/03/08/asp-net-mvc-using-json-standard-responses-for-your-ajax-calls/

Your response is completely acceptable if it's fitting your needs. If I was working with an API, I would see that error response as 'standard', containing a response code and description, although I might like a boolean success for ease of use.

like image 38
p e p Avatar answered Oct 27 '22 04:10

p e p


My 2 cents:

I would say that foremost the statuscode that you send back as the response is the best error indicator and gives a lot of options in the 4xx and 5xx range... (Even when you try to HttpGET some coffee from a teapot, you can use 418 :D)

As anything that is not 200 is some sort of error, and the http status codes are well documented in which case they should be used, any further error message is not really necessary (The error description is implied by the statuscode). Browsers are the ones doing the request, and they don't care about the errormessage, only the statuscode.

Any extra errormessages might also just away too much information to possible hack attempts. I mean, returning a 403 Forbidden is enough information on its own, you shouldn't also return a message saying "Not allowed, please use '1234' as the password instead" :)

like image 32
Céryl Wiltink Avatar answered Oct 27 '22 04:10

Céryl Wiltink