[Swift, Alamofire]: responseValidationFailed with error code 400 - swift

My problem is basically in the title. The code that I am trying to run is just below. VVV
let unfollow = "https://api.instagram.com/v1/users/\(userID)/relationship?access_token=\(access_token)&action=unfollow"
Alamofire.request(unfollow, method: .post).validate().responseJSON(completionHandler: {
response in
switch response.result {
case .success(let value):
let data = JSON(value)["data"]
print(data["outgoing_status"].stringValue)
case .failure(let error):
print(error)
}
})
The exact console error I recieve is: responseValidationFailed(Alamofire.AFError.ResponseValidationFailureReason.unacceptableStatusCode(400))
I am using the Instagram API by the way but I don't think that that is necessarily related to the issue.
Any help greatly appreciated.

The erro log responseValidationFailed(Alamofire.AFError.ResponseValidationFailureReason.unacceptableStatusCode(400)) clearly shows that you are getting 400 error. Which is explained in W3.org as
400 Bad Request:
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
So you need to chek you request URL if it is correct.
Also, you are using validate() method of request which is supposed to get response status codes 200...299, but you are getting 400 as response code. Thats why it is mentioned as unacceptableStatusCode(400) in error log.
Seel this also.

Related

In Locust I need to get original timeout or connection error when using catch_response=True to validate response

There is a good explanation how to validate response of the request
https://docs.locust.io/en/stable/writing-a-locustfile.html#validating-responses
However there are cases when status_code=0 (case of connection error or timeout).
I would like to be able to pass original error when it happens in response.failure().
For example:
with self.client.get("/some_test_url/", catch_response=True) as response:
if response.status_code == 200 and _some_other_errors_checks_:
response.failure("Response is 200 but contain _some_error_")
if response.status_code == 0: # This is case of timeout or connection error
response.failure(????????)
You could see the original error using response.error property.
If something happened and the response is an error response or contains an error you could raise the original error using response.raise_for_status() that will throw the original error of the response if exists

What response code should we use on a REST reply when the response data is an error message

We have a REST service where the response to a request may be an error message. A simple example is the request is a formula to calculate and the formula might have a divide by zero. In that case the response is an error code and error message.
So the communication with the REST service is all good. The service itself is responding to the request. But the response is an error message instead of the expected result.
In this case what is the best response code to use? 200 to say the entire communication process is good and we look in the returned JSON to determine if it’s an error? 500 to say it’s an error, but then look to see if we have the expected JSON to determine it was an error in the calculation? Some other code which says we are getting a response from the server but the response is an error message?
A simple example is the request is a formula to calculate and the formula might have a divide by zero. [...] In this case what is the best response code to use?
I would use 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.
Don't rely only on HTTP code anyway, always add a description of the error in the body. I believe it's common practice to have all your endpoints reply with a JSON with success (true or false) and something like error (with the error message) if success if false, or data (with the result) if success is true.
For error messages we can use 4XX Bad Request
Look at this post, for various status codes.
http://www.restapitutorial.com/httpstatuscodes.html

Which HTTP code should be return from REST API?

im currently working on a website which has Spring at backend and Angularjs at front side and we had discussed about back end responses to handle frontend's message dialogs and i have a question to ask:
Lets say i have an API :
GET : /getstatistics
Request params : fromTime,toTime ( in timestamp format)
And if client make a request with invalid params like a string, which response code should be returned from server ? HTTP 400 bad request and response body with a message " fromTime and toTime should be in timestamp format" or HTTP 200 with same message?
I saw some Google's APIs for example Oauth, they're returning code 200 for a request with invalid access_token but ,in our project my opinion it should be HTTP 400 because Javascript has success and error callbacks, is it better for it just pop a red color dialog with message inside rather than a HTTP 200 code then still need to check the content of the message?
Any advides and opinions are appreciated.
Thanks!
You should be returning a 400 error for bad request. Check out this reference.
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).
Please have a look at RFC7231#section-6
A client MUST understand the class of any status code, as indicated by
the first digit
and,
4xx (Client Error): The request contains bad syntax or cannot be
fulfilled
Bad syntax can be something like you've mentioned in your question (making a request with invalid parameters, like a string).
I keep these two references handy whenever I'm designing RESTful APIs, might be helpful for you too:
https://httpstatuses.com/
http://www.restapitutorial.com/httpstatuscodes.html
Yes you are right, the http code should be 400 in your case. Your discussion here normally should be whether you need to return 400 or 422. For this you can check the accepted response for this SO question 400 vs 422 response to POST of data
I think it has something to do with how the parameters are used. If you use the resource, then a 404 should return. If the data is simply not valid then we decide to set a 409 Status to the request. It can't full fill it at 100% because of missing/invalid parameter.
HTTP Status Code "409 Conflict" was for us a good try because it's
definition require to include enough information for the user to
recognize the source of the conflict.
Reference: w3.org/Protocols/
Edit:
In any case, the status code 200 is incorrect here because there is an error. In response, you can then return specific information like this:
{
"errors": [
{
"userMessage": "Sorry, the parameter xxx is not valid",
"internalMessage": "Invalid Time",
"code": 34,
"more info": "http://localhost/"
}
]
}

Try to serialize Object although Validation fails

I use ResponseObjectSerializable like described here:
https://github.com/Alamofire/Alamofire#generic-response-object-serialization
And i want to validate if the status code is in a range
https://github.com/Alamofire/Alamofire#validation
My call looks like this:
Alamofire.request(Router.Something())
.validate(statusCode: 200..<300)
.responseObject { (request, response, object:Object?, error) in
println(object)
println(request)
println(response)
}
My Problem is if the validation fails responseObject anyhow get called and try to serialize the empty response.
How I can handle that without validate the response a second time in my ResponseObjectSerializable?
That's a really good question.
The long story short is that you can't. Your responseObject serializer is not notified about a validation error. It only receives the request, response and data objects and needs to attempt to construct the object from the data.
The ResponseObjectSerializable link you posted does exactly that. If the serialization succeeds, it will return a valid object. If it fails, it will return a nil object and a serialization error.
Where it gets interesting is if you return a serialization error, but the validation also failed. In that case, your completionHandler will actually be called with a nil object, and the validation error, not the serialization error. Alamofire prioritizes the validation error over the serialization error if the validation is run before the responseObject.
As a sidenote, your responseObject serializer should handle the data coming back from the server safely, regardless of the status code that was returned. If parsing the data fails, your serializer should return a serialization error. If it succeeds, then return the object.

HTTP Response for Unsuccessful Handling of Request

Let's say I have a REST POST end-point: www.foo.com/id/X where X represents a number.
My server-side pseudocode looks like this:
performIdLookup(int id) {
if ( idExists(id) ) {
return toJson(lookup(id)) // returns 200/OK Status Code with object as JSON
}
else {
return HTTP_???_error
}
}
Per this question, sending a 400 error doesn't seem right here since the user submitted a valid request, but the server couldn't locate it.
What's the right HTTP response here and why?
That is very easy.
404 Not Found
If there is no resourece at /id/42, a resource can not be found for this URL.
See the list of HTTP status codes.
Not 400 (bad request). But 404 (not found). Yes, 404 is not what we are used to watching in these cases, but you can add some custom information with response.