Hacker News new | ask | show | jobs
by tarequeh 3625 days ago
Handling errors over REST API is something I've struggled with. What's the best way to handle errors? Data validation errors will be different from system/server errors. Tough to establish a universally applicable error response structure.

I used to be in favor of sending 200 responses with error codes but now gravitating back towards relaying the most relevant HTTP error & letting the clients handle it.

3 comments

Any app of decent size will probably end up passing HTTP's error codes. 200 + error is OK, except it can mess with caching. A 5xx with details in the response is fine.

You might be tempted to map some errors, like "item not found" to 404, and so on. But you still need to provide the real error code. So you're not gaining much.

Honestly, I don't get the obsession with using HTTP features to represent part of an API. It never saves work; you're writing a custom client each time anyways. From a purely code perspective, you're going to deserialize the body or a context object from a header. Moving that data into multiple headers can only require more code, not less. Same for verbs. I've never gotten any benefit beyond GET-for-read, POST-for-write.

Elasticsearch is a good example. The URL space is overloaded with special things, allows you to create objects you can't reference, and so on. They use verbs, except you still have extra parameters tacked on. There's zero benefit to me, the user, of them making it REST like.

Maybe if REST-someone creates a machine usable spec like WSDL (just "simpler") then all these HTTP headers could be put to use.

The advantage is that there is some level of standardization.

404? That means the entity doesn't exist. 302? I should look somewhere else. 401? The server doesn't know who I am.

Accept? I can specify the format. ETag? I can get a faster response if I include the token in the next request.

This stuff is really, really common, and people can learn your API very quickly. A transparent caching server can improve performance.

Sure, with a custom protocol you can get a tight system. Hell, write your own transport layer for even more control. But it will take longer to learn and harder to interoperate.

The time spent reading that 404 in this case means "the object ID isn't found" versus "this path doesn't exist" pretty much negates any benefit - you still have to include sub codes. Same for "access denied because token expired" vs "invalid token". Not mention all the stuff that'll get crammed into 400/500/503.

If your app is simple enough that all errors map 1:1 to HTTP, great. Or if it doesn't need that level of error management. Otherwise HTTP just confuses the issue.

So, you just want to explain the error further? Wonderful. RFC2616

> the server SHOULD include an entity containing an explanation of the error situation

---

The 3-digit status code tells consumers (1) the status category (success, redirect, client error, server error) and (2) a more specific status within that category. It does that in a way that doesn't require me turning to your API docs every 3 seconds.

WSDL-like descriptors for REST-like APIs:

[1] Swagger: http://swagger.io/

[2] RAML: http://raml.org/

[3] WADL: https://www.w3.org/Submission/wadl/

A big reason for using HTTP error codes and methods is transparency—you can easily see what's happening from looking at the server log.
Send the most appropriate HTTP status code, along with an error resource the client purports to understand (by accept header content negotiation).

If the client isn't declaring to accept a mediatype you produce, you send your fallback error format, which could be anything you choose: text/plain, or some custom format you design, or some generic hypermedia type that defines an error field.

Perhaps look at HTTP Problem Details? https://tools.ietf.org/html/rfc7807