HTTP error code for "another operation in progress" - rest

My app handles some HTTP requests which needs more time to complete. When request is successfully enqueued, app responds with 202 Accepted code. However there may be a case when another request is sent while previous one is not completed yet, and app needs to respond with error "another operation in progress" in such case. I checked list of HTTP errors but there is no error with similar description. The closest one which I found is 423 Locked. Is this the proper error for this case, or some other one would be better?

Http is stateless protocol without cookie/session mechanism. It means one http request doesnot matter with another http. If client and server is under your control, you could add your private status code. BTW 4xx is client side error, 5xx is server side error. 2xx is successful code. In this question , you may define your own 2xx code.

What you are describing to me sounds like 503 Service Unavailable.
There's nothing wrong with the request
We want the client to try again later
It's an usual problem to have - why not accept the request and then start work on it when the capacity is available? But in conditions where that isn't an acceptable option, sending a "I can't do that right now" message seems like a good fit.

Related

Should I throw a 400 or 500 service error for business logic fail?

I'm working on a music media library that allows users to share music in their library but only if they marked as shareable.
In the backend I'm checking if the music file is shareable like so
if(file.shareable) share
else throw 500 or 400?
To me this is a 400 bad request because the the user is trying to do something that the business does not allow.
Is this the corret way?
4xx indicates a bad request -- i.e. "don't try re-requesting".
5xx indicates that the server had a problem, i.e. "give us a minute, and try again later."
So if it's business logic, that would be a 400 level error, i.e. don't re-request.
You should use 4xx codes for any client error that prevents the server from returning a useful response. This includes requests that violates business rules. The point is to indicate to the client that the request is invalid, and potentially include steps the client can take to fix the situation.
Use 5xx codes if the server encounters an internal problem that prevents it from doing its work. Maybe the database or a necessary external service is down, or there's a programming error somewhere. Maybe the server is just too busy right now. Not much the client can do to fix that other than try again later.
Basically:
4xx: Your fault.
5xx: My fault.

HTTP error code when server cannot find a user-given external resource

Our image board allows users to upload images by copy-pasting URLs. A client app sends a POST request to our API with an image URL given in the request body. Our web service receives the POST request and handles it by downloading the image from the given URL by using a server-side HTTP client (request in our case).
In successful case, the service finds the image, downloads it, and stores it to the server. The service returns HTTP 200 to the client.
Now, what if the image cannot be found? What if the download attempt results in HTTP 404? What HTTP error code should we use to response to the client?
HTTP 400 Bad Request is not applicable because the request was well-formed and all parameters were valid.
HTTP 404 Not Found is not applicable because the request URL was found and served although the image URL was not.
HTTP 502 Bad Gateway does not feel right either because there is nothing wrong with our server or the upstream server (the server of the source image). The user just happened to type in an image URL that does not exist.
Any experience on the matter? Which error code is the most correct?
First of all you should decide if this is a client error (4xx) or server error (5xx). From what you describe, it feels more like a client error. The client has requested the creation of a resource from another resource (the image URL) which does not exist.
There is no perfect match for this scenario, although one could make a case for each of the 2 following response codes:
HTTP 409 Conflict: From the RFC:
The request could not be completed due to a conflict with the current
state of the target resource. This code is used in situations where
the user might be able to resolve the conflict and resubmit the
request...
This applies to your case if you consider the target resource to be in a bad state (image not found). If someone provides an image at the specified URL, that effectively transitions your resource to a valid state.
This is also a good match because, as the RFC states, this code implies the user might be able to resolve the conflict (in your case the user would correct this by posting the image to the specified URL).
HTTP 424 Failed Dependency: From the RFC:
The 424 (Failed Dependency) status code means that the method could
not be performed on the resource because the requested action depended
on another action and that action failed...
This applies to your case in that "the requested action depended on another action and that action failed". The dependent action is the posting of an image to the other URL. What you have described is a case where that dependent action either failed or did not happen (which could also be called a failure).
Since the API determines on something that is not available, its service is unavailable as well.
The status code 503: Service Unavailable is the best fit for your situation.
According to the RFC description:
The server is currently unable to handle the request due to a temporary overloading or maintenance of the server. The implication is that this is a temporary condition which will be alleviated after some delay. If known, the length of the delay MAY be indicated in a Retry-After header. If no Retry-After is given, the client SHOULD handle the response as it would for a 500 response.
Alternatively, if your API supports a way of communicating errors (e.g. to tell the user that the information he submitted is incorrect) you may be able to use this method to tell the user that the external resource is unavailable. This might be a little friendlier and might avoid some error raises on the user's side.
Since the client app sends POST requests to your API server the response codes should be generated according to the received server in your case this is your API server.
If the server has received correct information from the client app and server determines the request as valid, it should return apropriate code with proper JSON or header based error messages.
http error codes were conceived assuming that all pages possibly served were stored locally, one way or another.
Your scenario does not match that assumption and it should therefore not come as a surprise that you don't find codes that fit your bill properly.
Your "not found" scenario is in fact an application error and you should notify your user of the situation by providing an error message on the form where he entered the URL (or return a fully dedicated error page or some such). Or choose an http error nonetheless and accept the notion that it will be a poor fit no matter what.
Now, what if the image cannot be found? What if the download attempt results in HTTP 404? What HTTP error code should we use to response to the client?
The main thing to keep in mind: you are trying to fool the client into thinking that you are a web site - just a dumb document store which might respond to some content editing messages.
For the client, the primary means of communication is the body of the response. See RFC 7231
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 status code is meta-data: aimed at giving the generic components participating in the exchange a chance to know what is going on (examples: the web browser doesn't need to know what page you are asking for to recognize a redirection response returned by the server, the web browser asking for credentials when it receives a 401 unauthorized response, web caches invalidating entries, or not, depending on the status code returned by the response).
HTTP 400 Bad Request is not applicable because the request was well-formed and all parameters were valid.
Yes, that's exactly right.
I would probably use 500 Internal Server Error, on the grounds that there's nothing wrong with the _document that the server received, the problems are all involved in the side effects of the server's implementation.
A different approach you might consider: 202 Accepted. Roughly translated "I got your message, I understood your message, and I'll get around to it later." If you don't need the side effects to be synchronous, you can defer judgment. That allows you to do things like applying a retry strategy.
The representation sent with this response ought to describe the request's current status and point to (or embed) a status monitor that can provide the user with an estimate of when the request will be fulfilled.
"I'll get to it later; if you want to know how it is going, go ask him -->"
Because 202 is a non-error status code, its effect on caches is different from those of a 4xx or 5xx. If you are already thinking ahead about caching, you'll want to the implications of that in mind.

HTTP Status Code for External Dependency Error

What is the correct HTTP status code to return when a server is having issues communicating with an external API?
Say a client sends a valid request to my server A, A then queries server B's API in order to do something. However B's API is currently throwing 500's or is somehow unreachable, what status code should A return to the client? A 5* error doesn't seem correct because server A is functioning as it should, and a 4* error doesn't seem correct because the client is sending a valid request to A.
Did you consider status codes 502 and 504?
502 – The server while acting as a gateway or a proxy,
received an invalid response from the upstream server it accessed
in attempting to fulfill the request.
504 – The server, while acting as a gateway or proxy,
did not receive a timely response from the upstream server
specified by the URI (e.g. HTTP, FTP, LDAP)
or some other auxiliary server (e.g. DNS) it needed to access
in attempting to complete the request.
Of course, this would require a broad interpretation of "gateway" (implementation of interface A requiring a call to interface B), applied to the application layer. But this could be a nice way to say : "I cannot answer but it's not my fault nor yours".
Since the API relies on something that is not available, its service is unavailable as well.
I would think that the status code 503: Service Unavailable is the best fit for your situation. From the RFC description:
The server is currently unable to handle the request due to a temporary overloading or maintenance of the server. The implication is that this is a temporary condition which will be alleviated after some delay. If known, the length of the delay MAY be indicated in a Retry-After header. If no Retry-After is given, the client SHOULD handle the response as it would for a 500 response.
Granted, the description implies that this status code should be applied for errors on the server itself (and not to signal a problem with an external dependency). However, this is the best fit within the RFC status codes, and I wouldn't suggest using any custom status codes so anyone can understand them.
Alternatively, if your API supports a way of communicating errors (e.g. to tell the user that the ID he supplied is incorrect) you may be able to use this method to tell the user that the dependency is unavailable. This might be a little friendlier and might avoid some bug searching on the user's side, since at least some of the users won't be familiar with any status codes besides 403, 404 and maybe 500, depending on your audience.
You can refer this link.
HTTP Status 424 or 500 for error on external dependency
503 Service Unavailable looks perfect for the situation.
It's been a while that this question was asked.
Faced similar situation today. After exploring a bit, to me it makes more sense to send 424 FAILED_DEPENDENCY.

What should a RESTful client do with its POST, PUT, or DELETE request upon a server error (500)

I have a RESTful service that throws a 500 INTERNAL SERVER ERROR status upon an internal failure for a number of reasons: DB errors upon connectivity or field size, code bugs, or issues with a managed code call. The resulting unhandled exception is reported back by IIS as a 500. Is this an appropriate use of 500? It could imply "retry request" according to MSDN Common REST API Error Codes. The proper API error code I am seeking is something like "### Server will NEVER process this request until a code change is made, do not resend or you will be looping forever and DOSing my server". Would a 400 Bad Request be more appropriate? It seems as if this is indicating a malformed request syntax itself, not that the service choked.
Furthermore, what should a client do when it encounters such an error? The server does not want another RESTful operation exactly like the previous one. The user may have spent some time doing data entry. Now we have to talk them off the ledge. Perhaps they can fix it on their own and that is the best practice? What are some similar experiences developers have had and how was it solved? Thanks.
4xx errors are "something is wrong with the client, they're sending the wrong stuff".
5xx errors are "something is wrong with the server, sorry it's out sick today."
Which basically means there's nothing the client can imply from a 5xx error. It could be permanent, it could be transient, the client doesn't know.
IIS sends a 500 error because IT doesn't know what happened. If your app is blindly throwing exceptions up to the web tier, there's not much more it can do or say about it.
If the server logic somehow actually KNOWS what's wrong, and WHEN it might be fixed, it can send a 503 error, telling the client it's unavailable and a Retry-After header telling the client when it will be back.
As for a client behavior, it's sort of dependent on the clients history with the service. Maybe the service intermittently fails with 500 errors, and another request will just work. This could happen, say, if you have a set of load balanced servers. The first server they hit is sick, but perhaps not sick enough that the load balancer has taken it out of rotation yet. So, another server may be just fine -- in that case the client could just retry and see what happens.
But in the end, it's up to the client as to what to do. It could try a simple back off algorithm. Retry once or twice. Retry once immediately, then again in 10s.
Or it could just push the 500 error back to the user with a polite message "tough luck".
Only the client use cases and requirements can really dictate what it's behavior should be when the server is dead.
At the client side, we have to assume that the web-service is good, and that this either a malformed request (i.e. the user has keyed in something in-appropriate), or a network error of some kind. The method I used is to use an alert box, requesting the user to refresh the screen (F5), and try again with proper input. You may want to add "in case error persists, contact ...".

Correct HTTP status code for a not satisfiable REST request

I currently develop a task queue with a RESTful API.
In order to handle a task, a worker has to create a lease.
PUT .../leases
If the task queue has tasks available, this will succeed, a lease will be created and the server responds with status 201.
I am unsure how to handle this case when no tasks are available. It is not possible to create a lease, when no tasks are available. Which HTTP status code would be appropriate for this case?
204 No Content - The client hasn't made anything wrong, but there is no data.
400 Bad Request - This is imho not applicable, as it means "the request could not be understood by the server", which is not the case
In the meantime I thought that this approach might not be ideal. Either I use 503, as recommended of Brian and also backed by a passage of REST in practice, or I change the whole process.
I was thinking of leases which could be created tentatively. That means
PUT to /leases
Either create a lease, assign a task and respond with 201 or create a tentative lease and respond with 202
Tentative leases will stay for some time. If tasks gets available, they are assigned to the tentative leases. If there is no task for a specific period of time, the lease gets deleted and the server will respond with 410
The client should then start again with 1.
Since the resource is controlled by the server and there's nothing the client can do to influence the outcome, a 500-range code would be most appropriate.
503 - Service Unavailable sounds right to me. It implies that the server has not got enough resources available to meet the needs of the request. You should probably also return a meaningful error in the body of the response to make it explicitly clear that it failed because no leases/tasks were available, but that might not be the case sometime in the future.
404 - Not Found could be used. Wikipedia summarizes it as:
The requested resource could not be found but may be available again in the future. Subsequent requests by the client are permissible.
404 almost works, but I think of it as the resource you are dealing with and you are doing a PUT to create a resource. Of course it doesn't exist that's why you are creating it.
I would agree with your first thought on the 400 Bad Request in a narrow sense of the definition. But if you broaden the definition to include anything that could go wrong with the request then it would fit your situation and I think it's acceptable to do just that. For example we send a 400 back if the request didn't meet the schema we were expecting and if there are validation errors on the resource. For our service if we can programmatic determine that this is a bad request we send back a 400.
For your service the creation of a lease when no tasks are available constitutes a bad request, and you can send the 400 with text explaining what the problems is. I think the 400 was meant for a broader definition then what you are holding it to.
I don't think the 500's work because they are more unhandled stuff, and this is a case you can handle and provide informational responses to.
Hope this helps.
IIS sends a 405 Method Not Allowed if I try to use an unsupported method (ie PUT when it expects a GET). And it sends a 404 Not Found if the endpoint doesn't exist at all.