RetroFit status code 201 interpreted as error - retrofit

I am developing a RESTful API, which has an endpoint, that creates an entity. This endpoint is called with POST and responds with 201, and a field in the body.
I see that Retrofit, interprets this 201 response as failure and calls the failure() method. One solution would be to change the response code to 200, but does anyone know why is it doing that?
Thanks

From the documentation of the Callback class, we have:
failure(RetrofitError error)
Unsuccessful HTTP response due to network
failure, non-2XX status code, or unexpected exception.
That is, your 201 code status should be handled as success.
But there are some another causes for the issue you are facing. From this answer, you can see that retrofit can throws an exception that calls the failure method. Try see your gson parser, that is the POJO class that represents the expected response for this service.

Related

What's the suitable HTTP error for non requested required data

In my case there is no parameters required. In other words, the application does not expect any data via post, get or put. However, in the implementation a stored list of items in session variable should be defined first i.e. something like shopping cart items, the user collect items, and then go to the action below, otherwise, it should throw an HTTP error. Checkout the example below:
public function actionCreate(){
if(count(Yii::$app->session->get('versesList',[])) > 0){
// Do the logic
}
else{
throw new \yii\web\BadRequestHttpException(Yii::t('app', 'You must collect some verses first!'));
}
}
I don't know exactly, if the 400 bad request is the proper error code or not. I have tried reading List of HTTP status codes on the Wikipedia but I have gotten confused among some of the other HTTP errors such as: 406 Not Acceptable, 412 Precondition Failed,422 Unprocessable Entity
HTTP 400, since you are requesting an operation the server doesn't know how to handle (so it's a bad request).
RFC2731 states the following:
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).
400 is definitely fine for this case, but if you want to get more specific:
it sounds like the user needs to do some other HTTP request for this HTTP request to be valid. It's common to use 409 Conflict for these cases.
I wrote a bit more about this with additional examples on my blog, if it's interesting: https://evertpot.com/http/409-confict

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.

how to use HTTP 412 code

I am developing a RESTful web service. The web service receives XML from clients, it should reject some bad requests containing some error related to our business logic(say, the payment value below a minimum value). If rejecting request, a customised error code and error message will be written in a response XML(inside http response body). I also want to return a HTTP code in the status line, so client can recognize rejection right away without looking into the response boday. Some people suggest using HTTP code 412, however by looking at the definition of HTTP 412:
412 Precondition Failed
The precondition given in one or more of the request-header fields evaluated to false when it was tested on the server. This response code allows the client to place preconditions on the current resource metainformation (header field data) and thus prevent the requested method from being applied to a resource other than the one intended.
I don't quite understand what it represents for. Could someone explain the appropriate usage of 412 please? or in this case are there any better choices?
It's for use with conditional requests: http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p4-conditional-25.html.
You may want to look at 422 or 409 instead.

Should I use HTTP 4xx to indicate HTML form errors?

I just spent 20 minutes debugging some (django) unit tests. I was testing a view POST, and I was expecting a 302 return code, after which I asserted a bunch database entities were as expected. Turns out a recently merged commit had added a new form field, and my tests were failing because I wasn't including the correct form data.
The problem is that the tests were failing because the HTTP return code was 200, not 302, and I could only work out the problem by printing out the response HTTP and looking through it. Aside from the irritation of having to look through HTML to work out the problem, a 200 seems like the wrong code for a POST that doesn't get processed. A 4xx (client error) seems more appropriate. In addition, it would have made debugging the test a cinch, as the response code would have pointed me straight at the problem.
I've read about using 422 (Unprocessable Entity) as a possible return code within REST APIs, but can't find any evidence of using it within HTML views / handlers.
My question is - is anyone else doing this, and if not, why not?
[UPDATE 1]
Just to clarify, this question relates to HTML forms, and not an API.
It is also a question about HTTP response codes per se - not Django. That just happens to be what I'm using. I have removed the django tag.
[UPDATE 2]
Some further clarification, with W3C references (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html):
10.2 Successful 2xx
This class of status code indicates that the client's request was successfully received, understood, and accepted.
10.4 Client Error 4xx
The 4xx class of status code is intended for cases in which the client seems to have erred.
10.4.1 400 Bad Request
The request could not be understood by the server due to malformed syntax.
And from https://www.rfc-editor.org/rfc/rfc4918#page-78
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.
[UPDATE 3]
Digging in to it, 422 is a WebDAV extension[1], which may explain its obscurity. That said, since Twitter use 420 for their own purposes, I think I'll just whatever I want. But it will begin with a 4.
[UPDATE 4]
Notes on the use of custom response codes, and how they should be treated (if unrecognised), from HTTP 1.1 specification (https://www.rfc-editor.org/rfc/rfc2616#section-6.1.1):
HTTP status codes are extensible. HTTP applications are not required
to understand the meaning of all registered status codes, though such
understanding is obviously desirable. However, applications MUST
understand the class of any status code, as indicated by the first
digit, and treat any unrecognized response as being equivalent to the
x00 status code of that class, with the exception that an
unrecognized response MUST NOT be cached. For example, if an
unrecognized status code of 431 is received by the client, it can
safely assume that there was something wrong with its request and
treat the response as if it had received a 400 status code. In such
cases, user agents SHOULD present to the user the entity returned
with the response, since that entity is likely to include human-
readable information which will explain the unusual status.
[1] https://www.rfc-editor.org/rfc/rfc4918
You are right that 200 is wrong if the outcome is not success.
I'd also argue that a success-with-redirect-to-result-page should be 303, not 302.
4xx is correct for client error. 422 seems right to me. In any case, don't invent new 4xx codes without registering them through IANA.
It's obvious that some form POST requests should result in a 4xx HTTP error (e.g. wrong URL, lacking an expected field, failing to send an auth cookie), but mistyping passwords or accidentally omitting required fields are extremely common and expected occurrences in an application.
It doesn't seem clear from any spec that every form invalidation problem must constitute an HTTP error.
I guess my intuition is that, if a server sends a client a form, and the client promptly replies with a correctly-formed POST request to that form with all expected fields, a common business logic violation shouldn't be an HTTP error.
The situation seems even less defined if a client-side script is using HTTP as a transport mechanism. E.g. if a JSON-RPC requests sends form details, the server-side function is successfully called and the response returned to the caller, seems like a 200 success.
Anecdotally: Logging in with bad credentials yields a 200 from Facebook, Google, and Wikipedia, and a 204 from Amazon.
Ideally the IETF would clear this up with an RFC, maybe adding an HTTP error code for "the operation was not performed due to a form invalidation failure" or expanding the definition of 422 to cover this.
There doesn't appear to be an accepted answer, which to be honest, is a bit surprising. Form validation is such a cornerstone of web development that the fact that there is no response code to illustrate a validation failure seems like a missed opportunity. Particularly given the proliferation of automated testing. It doesn't seem practical to test the response by examining the HTML content for an error message rather than just testing the response code.
I stick by my assertion in the question that 200 is the wrong response code for a request that fails business rules - and that 302 is also inappropriate. (If a form fails validation, then it should not have updated any state on the server, is therefore idempotent, and there is no need to use the PRG pattern to prevent users from resubmitting the form. Let them.)
So, given that there isn't an 'approved' method, I'm currently testing (literally) with my own - 421. I will report back if we run into any issues with using non-standard HTTP status codes.
If there are no updates to this answer, then we're using it in production, it works, and you could do the same.
The POST returns 200 if you do not redirect.
The 302 is not sent automatically in headers after POST request, so you have to send the header (https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpResponse) manually and the code does not relay on data of the form.
The reason of the redirection back to the form (or whatever) with code 302 is to disallow browser to send the data repeatedly on refresh or history browsing.

RESTful service, how to respond if validation failed?

I have service that takes some entity and needs to save/update this entity:
http://myhost.com/rest/entity
I use POST and submit JSON. Inside service it detects that entity passed is not good. Not valid, order passed in with customer that doesn not exist, etc.
How should I reply? HttpCode.NotFound? Or others? How do you reply to such things?
422 Unprocessable Entity, defined in WebDAV (RFC 4918):
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.
In our project in such situations we do the following:
Set response code to HTTP 400 Bad Request
Set response body to the following JSON: {"message":"%extended error message here%"}
But it's really very subjective.
Also I'd suggest reading This blog article on RESTfull error handling - it describes many available options, so you can choose something for your taste.
I think you should pick a client error code. 400 Bad Request or 403 Forbidden can be a good start

Resources