HTTP status code for "success with errors"? - http

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?

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 -
A POST request tries to modify data on the server
If the server fails, it sends a 500 error to indicate failure
If the server succeeds, it sends a 302 redirect response
The browser then sends a fresh GET request to the server
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.

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.

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.

Related

What is the most appropriate HTTP response from a backend service when attempting to remove an entry that no longer exists in the Database?

My team is developing a simple backend service that provides the operations ADD, GET and REMOVE a very simple item. All are triggered by an http request and they do not much besides adding, getting and removing the item from a database.
Regarding the specific scenario in which a REMOVE operation is triggered on a item that is not present in the DB (e.g. was removed before), our question is what should be the response of the service? We having been debating options like 200 + some specific message, 410 - resource gone, amongst other 2XX and 4XX possibilities, but we haven't reached a consensus.
I hope this is not Bikeshedding.
Thank you for your help.
What should be the response of the service?
It's important to highlight that status codes are meant to indicate the result of the server's attempt to understand and satisfy the client request. Having said that, 2xx status codes are unsuitable for this situation and should be avoided:
The 2xx (Successful) class of status code indicates that the client's request was successfully received, understood, and accepted.
The most suitable status code would be in the 4xx range:
The 4xx (Client Error) class of status code indicates that the client seems to have erred. Except when responding to a HEAD request, the server SHOULD send a representation containing an explanation of the error situation, and whether it is a temporary or permanent condition.
The 404 status code seems to be what you are looking for, as it indicates that the server can't find the requested resource:
6.5.4. 404 Not Found
The 404 (Not Found) status code indicates that the origin server did not find a current representation for the target resource or is not willing to disclose that one exists. A 404 status code does not indicate whether this lack of representation is temporary or permanent; [...]
If you are concerned on how the client will understand the 404 reponse, you could provide them with a payload stating that such resource is no longer available.
And just bear in mind that ADD and REMOVE are not standard HTTP methods. Hopefully that was a typo and you are using POST (or PUT) and DELETE to express operations over your resources.

Which HTTP status code should be used for business errors in API design?

Lets say I have an API endpoint that executes some business operation which can result in many different failures that are not connected directly to the request.
The request is correctly formed and I cannot return 4xx failures, but the logic of the application dictates that I return different error messages.
Now I want the client to be able to differentiate these error messages so that different actions can be taken depending on the code. I can return a custom JSON like this e.g.
{
"code": 15,
"message": "Some business error has occurred"
}
Now the question is which HTTP status code should I use for such occasions if no standard code like Conflict or NotFound makes sense.
It seems that 500 InternalServerError is logical, but then how can I additionally flag that this cannot be retried, should it be just documented that given status codes is not possible to retry so one can retry if you don't get one of those?
Consult RFC 7231:
503 Service Unavailable looks like a potential candidate, but the RFC mentions that this is supposed to represent a problem "which will likely be alleviated after some delay." This would indicate to a client that it could try the same call later, maybe after business hours or on the weekend. This is not what you want.
501 Not Implemented could be possible, but the RFC mentions "This
is the appropriate response when the server does not recognize the
request method and is not capable of supporting it for any resource. A 501 response is cacheable by default;" This does not appear to be the case here - the HTTP method itself was presumably valid - the failure here seems to be happening at the business rules layer (e.g. sending in an account number that is not in the database), rather than an HTTP method (GET, POST, etc.) that you never got around to implementing.
That leaves the last serious candidate,
500 Internal Server Error
The 500 (Internal Server Error) status code indicates that the server
encountered an unexpected condition that prevented it from fulfilling
the request.
This is the error code that is normally used for generic "an exception occurred in the app" situations. 500 is the best choice.
As to how to distinguish this from a "temporal internal trouble" error, you can include this as part of the HTTP body - just make sure that your client can parse out the custom codes!

Does 200 mean the request successfully started or successfully finished?

I realize this might sound like an odd question, but I'm seeing some odd results in my network calls so I'm trying to figure out if perhaps I'm misunderstanding something.
I see situations where in isolated incidents, when I'm uploading data, even though the response is 200, the data doesn't appear on the server. My guess is that the 200 response arrives during the initial HTTP handshake and then something goes wrong after the fact. Is that a correct interpretation of the order of events? Or is the 200 delivered once the server has collected whatever data the sending Header tells it is in the request? (cause if so then I'm back to the drawing board as to how I'm seeing what I'm seeing).
It means it has been successfully finished. From the HTTP /1.1 Spec
10.2.1 200 OK
The request has succeeded. The information returned with the response is dependent on the method used in the request, for example:
GET an entity corresponding to the requested resource is sent in the response;
HEAD the entity-header fields corresponding to the requested resource are sent in the response without any message-body;
POST an entity describing or containing the result of the action;
TRACE an entity containing the request message as received by the end server.
Finished. It doesn't make sense otherwise. Something might go wrong and the code could throw an error. How could the server send that error code when it already sent 200 OK.
What you experience might be lag, caching, detached thread running after the server sent the 200 etc.
A success reply, like 200, is not sent until after server has received and processed the full request. Error replies, on the other hand, may be sent before the request is fully received. If that happens, stop sending your request.

Which HTTP status code means "Not Ready Yet, Try Again Later"? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
This post was edited and submitted for review 9 months ago and failed to reopen the post:
Original close reason(s) were not resolved
Improve this question
I'm developing a RESTful API in which http://server/thingyapi/thingyblob/1234 returns the file (aka "blob") associated with item #1234 to download. But the request could be made before the file has been generated. It definitely will be available at a later time.
There's a batch process in the server that generates all the blobs. Item 1234 already exists and its data, other than the blob, is already available. The server just hasn't generated 1234's blob yet.
I don't want to return 404; that's for things that do not exist. This will exist, but hasn't been generated yet. Kinda like a YouTube video that's "processing." I don't think redirection codes would be proper either; there's no "other" URL to try.
What's the correct HTTP status code to return in such a case?
The "problem", such as it is, is on the server side: the client has made a well formed request, but the server can not satisfy it. So I'm inclined to a "Server Error", 5xx status code.
Quoth RFC 7231 (the current HTTP standard, emphasis added):
The 5xx (Server Error) class of status code indicates that the server
is aware that it has erred or is incapable of performing the
requested method. Except when responding to a HEAD request, the
server SHOULD send a representation containing an explanation of the
error situation, and whether it is a temporary or permanent condition.
Note
"erred or is incapable of performing the request": despite their title of "Server Error", they are not just for server errors.
"temporary or permanent": these codes are suitable for temporarily unavailable resources, like yours.
Of the available codes, I'd say 503, "Service Unavailable" was the best fit:
The 503 (Service Unavailable) status code indicates that the server
is currently unable to handle the request due to a temporary overload
or scheduled maintenance, which will likely be alleviated after some
delay. The server MAY send a Retry-After header field... to suggest an appropriate amount of time for the
client to wait before retrying the request.
Note:
"likely be alleviated after some delay": true for your case.
"temporary overload": not pedantically true for your case. But, it could be argued, were your server much faster, the batch processing would have already been done when the client made the request, so it is a kind of "overload": the client is asking for resources faster than the server can make them available.
Retrying is suitable for your service, so your reply ought to include a Retry-After value. You could provide as the value the estimated completion time of the next execution of the batch process, or the execution interval of the batch process.
Defining your own 5xx status code (591, for example), although permitted, would have the wrong semantics:
a client MUST
understand the class of any status code, as indicated by the first
digit, and treat an unrecognized status code as being equivalent to
the x00 status code of that class
Clients would treat your own status code as 500, "Internal Server Error", which would not be right.
I suggest 202 - Accepted. From the documentation:
The request has been accepted for processing, but the processing has not been completed. [...]
Its purpose is to allow a server to accept a request for some other process (perhaps a batch-oriented process that is only run once per day)
I think that 423 - Locked can be used for this purpose:
The 423 (Locked) status code means the source or destination resource of a method is locked. This response SHOULD contain an appropriate precondition or postcondition code, such as 'lock-token-submitted' or 'no-conflicting-lock'.
I don't want to return 404; that's for thingies that do not exist.
The URL doesn't correspond to a request for a thingy.
http://server/thingyapi/thingyblob/1234
The client is requesting a thingyblob, which doesn't exist. If it existed, you would give it to them.
404.
Another option: 503 - Service Unavailable.
Since your resource is not ready, you probably know when (approximately) it will be available and when client may retry his request. This means you might want to utilize Retry-After header. This header is valid with 503 (Service Unavailable), which means whole site is down for maintenance, and 3xx (Redirection) responses.
In my opinion 302 (Found) with Retry-After header would be the best option, but I am not sure if Location field of response header can be equal to request url. It's circular redirect, anyway.
409 Conflict
Indicates that the request could not be processed because of conflict in the request, such as an edit conflict in the case of multiple updates. [Source Wikipedia.]
This could be appropriate.
If you cant fulfill the request by returning the data - then its not a success. I think 202 suggests the server has queued the request and it will fulfill the request later. But in your case, the request is for data now and has failed. If you retry later it is a different request.
I think you have a conflict.. you want the data.. but its being edited / updated. This would also be the case if Thingy1234 already existed and had been successfully downloaded before, but now was in the process of being edited was was unavailable whilst the edit was taking place.
501 - Not Implemented
Exactly like how it sounds. A feature that is not yet implemented, but implies future availability.
Here is a link to a summary of 5xx errors.

Which HTTP status code to use for required parameters not provided?

I have several pages designed to be called with AJAX - I have them return an abnormal status code if they can't be displayed, and my javascript will show an error box accordingly.
For example, if the user is not authenticated or their session has timed out and they try to call one of the AJAX pages, it will return 401 Unathorized.
I also have some return 500 Internal Server Error if something really odd happens server-side.
What status code should I return if one of these pages was called without required parameters? (and therefore can't return any content).
I had a look at the wikipedia article on HTTP status codes, but the closest one I could find to the code I'm looking for was this:
422 Unprocessable Entity
The request was well-formed but was unable to be followed due to semantic errors.
Edit: The above code is WebDAV specific and therefore unlikely to be appropriate in this case
Can anyone think of an appropriate code to return?
What status code should I return if one of these pages was called without required parameters? (and therefore can't return any content).
You could pick 404 Not Found:
The server has not found anything matching the Request-URI [assuming your required parameters are part of the URI, i.e. $_GET]. No indication is given of whether the condition is temporary or permanent. The 410 (Gone) status code SHOULD be used if the server knows, through some internally configurable mechanism, that an old resource is permanently unavailable and has no forwarding address. This status code is commonly used when the server does not wish to reveal exactly why the request has been refused, or when no other response is applicable.
(highlight by me)
404 Not Found is a subset of 400 Bad Request which could be taken as well because it's very clear about what this is:
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
This is normally more common with missing/wrong-named post fields, less with get requests.
As Luca Fagioli comments, strictly speaking 404, etc. are not a subset of the 400 code, and correctly speaking is that they fall into the 4xx class that denotes the server things this is a client error.
In that 4xx class, a server should signal whether the error situation is permanent or temporary, which includes to not signal any of it when this makes sense, e.g. it can't be said or would not be of benefit to share. 404 is useful in that case, 400 is useful to signal the client to not repeat the request unchanged. In the 400 case, it is important then for any request method but a HEAD request, to communicate back all the information so that a consumer can verify the request message was received complete by the server and the specifics of "bad" in the request are visible from the response message body (to reduce guesswork).
I can't actually suggest that you pick a WEBDAV response code that does not exist for HTTP clients using hypertext, but you could, it's totally valid, you're the server coder, you can actually take any HTTP response status code you see fit for your HTTP client of which you are the designer as well:
11.2. 422 Unprocessable Entity
The 422 (Unprocessable Entity) status code means the server
understands the content type of the request entity (hence a
415(Unsupported Media Type) status code is inappropriate), and the
syntax of the request entity is correct (thus a 400 (Bad Request)
status code is inappropriate) but was unable to process the contained
instructions. For example, this error condition may occur if an XML
request body contains well-formed (i.e., syntactically correct), but
semantically erroneous, XML instructions.
IIRC request entity is the request body. So if you're operating with request bodies, it might be appropriate as Julian wrote.
You commented:
IMHO, the text for 400 speaks of malformed syntax. I would assume the syntax here relates to the syntax of HTTP string that the client sends across to the server.
That could be, but it can be anything syntactically expressed, the whole request, only some request headers, or a specific request header, the request URI etc.. 400 Is not specifically about "HTTP string syntax", it's infact the general answer to a client error:
The 4xx class of status code is intended for cases in which the client seems to have erred. Except when responding to a HEAD request, the server SHOULD include an entity containing an explanation of the error situation, and whether it is a temporary or permanent condition. These status codes are applicable to any request method. User agents SHOULD display any included entity to the user.
The important part is here that you must tell the client what went wrong. The status code is just telling that something went wrong (in the 4xx class), but HTTP has not been specifically designed to make a missing query-info part parameter noteable as error condition. By fact, URI only knows that there is a query-info part and not what it means.
If you think 400 is too broad I suggest you pick 404 if the problem is URI related, e.g. $_GET variables.
I don't know about the RFC writers' intentions, but the status code I have seen used in the wild for that case is 400 Bad Request.
422 is a regular HTTP status code; and it is used outside WebDAV. Contrary to what others say, there's no problem with that; HTTP has a status code registry for a reason.
See http://www.iana.org/assignments/http-status-codes
Read this carefully:
https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
422 is a WebDAV-specific thing, and I haven't seen it used for anything else.
400, even though not intended for this particular purpose, seems to be a common choice.
404 is also a viable choice if your API is RESTful or similar (using the path part of the URI to indicate search parameters)
Description as quoted against 400
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
(Emphasis mine)
That speaks of malformed syntax, which is not the case when the browser sends a request to the server. Its just the case of missing parameters (while there's no malformed syntax).
I would suggest stick with 404 :)
(Experts correct me if I am wrong anywhere :) )
I need to answer this old question because the most upvoted and accepted answer is plain wrong.
From RFC 9110 - HTTP Semantics:
The 400 (Bad Request) status code indicates that the server cannot or
will not process the request due to something that is perceived to be
a client error (e.g., malformed request syntax, invalid request
message framing, or deceptive request routing).
So 400 is what you have to use.
Do not use 404, because you will completely mislead the API consumer. 404 means that the resource was not found on the server:
The 404 (Not Found) status code indicates that the origin server did
not find a current representation for the target resource or is not
willing to disclose that one exists.

Resources