views:

81

answers:

3

I've poked around a bit, but I don't see an HTTP status code for when a request's succeeds, but there is an error after the "point of no return".

e.g., Say you process a request, its committed to the database, but while returning the result you run of memory, or encounter a NPE, or what have you. It would have been a 200 response, but now, internally, you aren't able to return the proper, well-formed response.

202 Accepted doesn't seem to fit since we've already processed the request.

What status code means "Success, but errors"? Does one even exist?

+1  A: 

If the server is aware that it has encountered a problem, it should normally return a 5xx error. The most generic one is the 500 Server Error, which the RFC 2616 defines as follows:

500 Internal Server Error

The server encountered an unexpected condition which prevented it from fulfilling the request.

Then it's the client's responsibility to reattempt the request. If the previous request was partially committed, it's the server's (or the database's) responsibility to roll that back, or to handle the duplicate transaction appropriately.

Daniel Vassallo
I'm not really satisfied with this answer. What does "fulfill" mean, exactly? We've modified the resource in whatever way the client requested. If they reload the page, they'll see the changes. As far as the user is concerned, it was successful. To me, it really sounds like we've fulfilled the _request_, but haven't fulfilled the _response_.
Richard Levasseur
@Richard: I always understood "fulfill" to include the response as well (but I might be wrong on this). Nevertheless, this status code is very generic, and it should be used whenever the server encounters a problem which cannot be described by another more specific 5xx error. I think [@Jim](http://stackoverflow.com/users/45935/jim-ferrans) described what I intended to say better, [in the other answer](http://stackoverflow.com/questions/3066972/http-status-code-for-success-with-errors/3067090#3067090).
Daniel Vassallo
+1  A: 

I agree with @Daniel that the proper response is an HTTP 500 (server error). The web application has to be written to roll back the transaction when there is an error, not leave things half-finished.

One thing you can leverage in your web application is "idempotency". This is the property of a function (or operation) that you can repeat it as many times as you like with the same result. For instance if a read fails, the client can simply retry it until it succeeds. If a deletion appears to fail, the client can again retry and the server will treat the request as valid whether or not the resource being deleted is already gone. And if an update appears to fail, the client can retry that until it gets a successful return from the server. The REST approach to architecting web services makes heavy use of idempotency to make operations robust in the face of error.

Jim Ferrans
To clarify, the transaction is already committed (e.g, consider the case when OutOfMemoryError occurs during the encoding of the response). To implement idempotency, you would need to implement revision control, no? Having the server keep track of submitted changes and clients supply and change id. There's also the case of handling non-temporary errors (say there is a bug resulting in a NPE instead of an out of memory error) - the client can retry all they'd like, but it'll never succeed (despite it having succeeded the first time, and the subsequent times being redundant).
Richard Levasseur
@Richard: It "all depends". If it's a content management app and you don't mind if two "simultaneous" updates seem to happen out of strict order occasionally, you don't have to do versioning. But versioning or timestamping might be appropriate if you have tighter constraints. Another approach is to form as much of your response within the confines of the transaction as you can, so an OOME would cause the transaction to abort. And maybe persistent message queues holding transaction requests and results could be what you want (check out Apache's ActiveMQ). +1 for the probing questions!
Jim Ferrans
A: 

HTTP doesn't have such a status code, but there is a best practice that allows you to handle such situations - redirect the user after a POST operation.

Here is a break down -

  1. A POST request tries to modify data on the server
  2. If the server fails, it sends a 500 error to indicate failure
  3. If the server succeeds, it sends a 302 redirect response
  4. The browser then sends a fresh GET request to the server
  5. If this fails, you get a 500 error, otherwise you get a 200

So, your use case of 'Saved data but can't retrieve it immediately' translates to a 302 redirect for the initial POST, followed by a 500 for the subsequent GET.

This approach has other advantages - you get rid of the annoying 'Are you sure you want to resubmit the data?' message. Also keeps your back/forward/refresh buttons usable.

sri