Http Response Code for Expected Server Error - http

What is the recommended HTTP response code for an expected server error? I know that 500 is for a server error, but it is typically for an unexpected error.
What if you wanted to throw an exception and allow the client to deal with it? Doesn't a 500 response code seem incorrect for that? What number should be used?

HTTP response codes should only reflect the status of the request itself. Something like a spam filter is endemic to the workings of your application, and has no bearing on the status of the HTTP request and response. Similar question here: How to show the internal server errors to the user?

The website posts a call to our server. We do a spam check. If it is spam, we throw an exception.
That is not an expected server error, that's a client performing an invalid request. Take a look at the 4xx range.

Related

What is the use of http_errors in guzzle?

I have read https://docs.guzzlephp.org/en/stable/request-options.html#http-errors documentation. However, I am not getting when to set it true/false.
If anyone can explain it with example, that would be very helpful to me.
Thank you,
Trupti
Take a look at status codes HTTP response status codes
This is what is written in guzzle docs for http errors.
Set to false to disable throwing exceptions on an HTTP protocol errors (i.e., 4xx and 5xx responses). Exceptions are thrown by default when HTTP protocol errors are encountered.
It is not possible that everything is ok when you send a http request for a web uri, you can get different errors like Connection errors, server errors, even client errors.
So in order to handle these there are different status codes used ranging between 400-499 & 500-599.
For requests to be send by guzzle, these are handled by GuzzleException. see the heirarchy of errors here.
So by sending requests with http_errors as false, you are telling that do not bother me throwing the errors of range 400-499(handled by ClientException) and 500-599(ServerException)
$client->request('GET', '/status/500', ['http_errors' => false]);
So guzzle will not inform you if your request has any of these errors(eg 403).

Is it suitable to use 200 HTTP status code for a forbidden web page?

What is the difference when we use 200 response status code for a forbidden page with an error message saying 'Access Denied' instead of using 403 response status code?
Are there any security implications?
The HTTP Response codes convey information about how the server has processed your request. So, if the server responds with 200, it means: "OK, I have received your request and processed it successfully". If it returns 403, it would mean: "I received your request successfully, but you don't have access to this resource".
However, technically they are both returned in the same format, in the same way in the response HTTP header like this:
HTTP/1.1 200 OK
HTTP/1.1 403 Forbidden
The difference is in the meaning. And the meanings are defined in the standard.
So, when you are responding with code 200, you are telling the client that it is all good and dandy. If you are responding to client with 403, you are saying that the client doesn't have permission to this resource. Remember, there can be different clients: web browsers, crawlers, ajax requests from javascript, etc.
So, if you are sending a login form with 200 code:
Users who are using a web browser would understand that they need to login.
Google crawler will index your members/quality-content URL with the login form and will not understand that actually, the original content is different and it should not index this page with the login form.
Javascript with ajax callback will run success callback, when it should be running error callback function.
So, basically, make us all a favour and follow the standards! :)
Answering your second question, no it does not make your application any less secure.
The reason for this decision might be that error message was not visiable using Internet explorer like described here: How do I suppress "friendly error messages" in Internet Explorer?
Actually the correct way is to use the right HTTP error code and make the error message longer than 512 bytes as described here:
https://support.microsoft.com/en-us/kb/294807
Response status codes are intended to help the client to understand the result of the request. Whenever possible, you should use the proper status codes.
The semantics of the status codes are defined in the RFC 7231, the current reference for HTTP/1.1.
While the 200 status code indicates that the request has succeeded, the 403 status code indicates that the server understood the request but refuses to authorize it:
6.3.1. 200 OK
The 200 (OK) status code indicates that the request has succeeded. The payload sent in a 200 response depends on the request method. [...]
6.5.3. 403 Forbidden
The 403 (Forbidden) status code indicates that the server understood the request but refuses to authorize it. A server that wishes to make public why the request has been forbidden can describe that reason in the response payload (if any). [...]
Returning 200 will work, for sure. But why would you return 200 if you can return a much more meaningful status code? If is there any good reason, this should be added to your question.

When should an API throw a 4xx status code (error) and when a 5xx?

This is a theoretical question.
I believe I know the answer but I've received contradicting answers, so I figured I'd ask here.
On the W3C site it says:
Client Error 4xx
The 4xx class of status code is intended for cases in which the client
seems to have erred.
It also says
Server Error 5xx
Response status codes beginning with the digit "5" indicate cases in
which the server is aware that it has erred or is incapable of
performing the request.
I take this to mean that if a request is syntactically correct, but logically wrong, such as an attempt to create an object with an invalid value on a specific property, then my API should throw a 5xx Error, because the server DID understand the request, but found it to be invalid.
I have, on the other hand, been told that it should be a 4xx error (specifically 400 Bad Request) because the logical error was on the client side, as it sent an invalid value in the first place.
So, what error code SHOULD I be reporting?
5xx error will occur when the problem is on the server side. For example when you make a request with a method or protocol which is not understood by the server, when the proxy did not respond, etc. Per short: when the server was unable to fulfill the request.
In your example a 4xx error is more appropriate, because the request initiator is the source of the problem. More specific, "422 Unprocessable Entity" error is appropriate, because as RFC 4918 states:
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.
From various reasons some API designers are trying to limit themselves to a set of 3 - 5 status codes that will be used. In general this is done to ease the work for the API users, which sounds good, but sometimes this philosophy can have bigger implications.
For example, if I send a request to some API to add a new comment, I would expect a few things to be granted, like (but not limited to):
The request is POST or send me back a 405 status if not.
If the comment was added I will get back 201 response with a link to my new comment in the body.
What do I get sometimes ?
If the request method is not POST, I will get a 400 error.
If the request is POST, I will get back a 200 status and sometimes no link to my new comment.
Sounds confusing ? For me it does.

What is the correct HTTP status for exceptions?

What HTTP status should I return if my script throws an exception?
200 OK
or
500 Internal Server Error
Let's say user request parameters are correct but there is a bug in my script which causes an error message to appear instead of a proper response (XML, JSON or other format). What should be the HTTP status?
500 Internal Server Error is the correct status if the error can't be fixed by the client changing their request.
Use any of the 4XX statuses if the client might be able to fix their request to avoid the error (or 404 if the resource wasn't found).
200 OK is not the appropriate status in almost any error situation, because then the client thinks things are running normally (which they are not) and may continue to make the same error-causing requests.
Familiarize yourself with the available status codes in RFC2616 and find one that most appropriately fits the situation.
It depends on why the exception is thrown since they can be used for almost any error. If it's thrown because some id in the URI is not found in the database I'd say 404. On the other hand if it's because the database is down I would throw a 500. If an exception is thrown but the resulting page would still be useful to the user I would say return 200.
Review the Status Code Definitions. 500 or 400 should do for general issues, however, the more detailed you can be then the more useful the returned status will be.

HTTP status code for "success with errors"?

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.

Resources