Several times before I used the method...
NSURLResponse *response;
NSError *error;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
to send/receive data synchronously when in an NSOperation and it has worked.
I'm working on a new project (new API, new server) now and the error just isn't being populated.
I'm using Charles proxy to snoop the network traffic and I can see "Response Code 500 Internal Server Error" coming back from the failed request in Charles but in the app the error object is always nil.
Like I said, I've used this loads before and the error is always populated if an error occurs.
Is there something on the server side that I can point out to the server side dev? He's adamant that I must be doing something wrong. The only thing I don't understand is that Charles is picking up response code 500 from it.
N.B. The problem is not that the error is occurring. The problem is that when it does occur the NSError object is not reporting it back to me. Just to clear it up in case anyone tells me to ask the server dev to fix the error. :-)
Your error object is not populated because the request succeeded from NSURLConnection's perspective -- that is, it was able to send data to the server and receive a response.
For protocol-specific errors, you need to inspect the NSURLResponse you get back. In this case, cast the response to NSHTTPURLResponse and invoke -statusCode.
The error is only populated if there is no response from the server or not a valid HTTP response, e.g. connection loss etc.
"Response Code 500 Internal Server Error" means there was an internal server error and your server returns an HTTP message with the response code 500. You should use NSHTTPURLResponse instead of NSURLResponse and call the statusCode method to check the HTTP response code. If the response code starts with 2 everything is fine. So I usually have a check like this: statusCode / 100 == 2.
For more HTTP response codes see http://en.wikipedia.org/w/index.php?title=HTTP_response_codes
Related
When API request fails, I need to know number of failed attempts. Backend has added a property ‘attempts’ to error object. How can I find this value, since NSError is not KV pairing compliant and I don’t see it when I log the error object to console.
If you are using NSURLSession for urlrequest , then you will have delegate methods for NSURLSession responses , they are:
->didReceiveResponse = here you receive the response that urlrequest has completed and response received status
->didReceiveData = here you get the SUCCESS response date for your request
->didCompleteWithError = here you get the FAILURE response (i.e) ERROR callback ,this is called every time when request fails , which gives you error data
I am confused about this method, specially about the error part and the documentation. Here on the documentation it says that
If the request completes successfully, the data parameter of the
handler block contains the resource data, and the error parameter is
nil. If the request fails, the data parameter is nil and the error
parameter contain information about the failure.
The problem is that, I have seen that some http response error codes fall into the "there is an error" and some dont, furthermore I can have data and error at the same time (but supposedly one should be nil at all times according to the documentation).
[NSURLConnection sendAsynchronousRequest:theRequest
queue:[[NSOperationQueue alloc] init]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
For example, my server sends a 401 response if the user uses wrong credentials, and this is cached inside the error clause, but if i send a 409 (duplicate entry) this is NOT cached by it. Im having some issues redirecting the flow because of this, im not sure what this method will consider an error and what it will not.
Also, how do i properly check for this?, I thought that just checking if there is an error, and then checking what was the code of the response would suffice to display a message or take an action, but as I described before, some "error" codes don't necessarily generate the error object. Should i first check for the status code?
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
int responseStatusCode = [httpResponse statusCode];
if (responseStatusCode == 200)
{
// If 200, assume everything went well?
} else
{
// Something went wrong, check for the code and the error here?
}
From my experience an error occurs when there is no response at all from the server, that's why the data is 0. If a server returns 400 or 500 error then these are a response from your server and depending on your server code maybe an error message you can parse.
Does
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
return error = nil when data is not nil?
if there is data returned, is error always nil?
that's what the documentation says ...
how is error affected by the http status code?
like if the status code is not 200, does it always return an error?
The NSError is not related with the HTTP Response. The NSError is returned when the connection itself failed. A bad HTTP status code means the request itself works for the client.
You have to manually check the status code.
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
int responseStatusCode = [httpResponse statusCode];
Now you can test if the status is 200.
To answer to your questions :
return error = nil when data is not nil?
if there is data returned, is error always nil?
If the data == nil then you should have error != nil
how is error affected by the http status code? like if the status code
is not 200, does it always return an error?
If you got a status code then it means the connection worked (from a connection request point of view, not the HTTP one) so error == nil and data should be not nil
You answered your first two questions yourself already. The documentation is right there.
Regarding the status code: No, status codes do not affect the NSError at all. This NSError is reserved for when a NSURLConnection actually fails in a non-HTTP way. For example when you're actually offline and no request can be made at all. Also keep in mind, that NSURLConnection is not tied to HTTP requests in any way. iOS also supports FTP connections out of the box (no status code like in HTTP here) and you can even write your own protocol support for almost anything you can think of.
Of course there will just occure an NSError if the request failed to get the data. But if the server returns you any other status code than 200, it will be like an error because you couldn't get the data. But by checking the status code you can give more specific error messages to the user instead of just Couldn't load data, because you can specify if there was an NSError which could be caused by missing internet connection or if you received any bad status code and the server is not available..
We've generally had success loading JSON-encoded data from our server using:
NSError* error;
NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:path]
options:NSDataReadingUncached
error:&error];
(On a background thread to avoid blocking the main thread.) But, with increasing server load, we've recently seen an invalid but non-error (error == nil) server response of:
<html><body><script>document.cookie='ggggggg=00268082ggggggg_00268082;
path=/';window.location.href=window.location.href;</script></body></html>
A retry will often result in successful download of expected JSON-encoded data; the problem appears to be server-side. Three questions:
1) Does anyone recognize this server response?
2) Is our server attempting to create a cookie instead of returning our file/data!?
3) If so, where should we be looking to understand how to avoid this random cookie response from our server?
Based on message board traffic, we were able to confirm that the problem could be reproduced by a variety of means (app, browser, or command line) -- the issue had nothing to do with iOS or our application code. We were able to sporadically reproduce the problem from the command line with curl using the form:
curl -D - your-test-url-here -s
After further investigation by our ISP, they determined that the most likely cause of the invalid HTTP response was from their DDoS attack protection. After they reset the affected server(s), the problem was resolved.
Is there an easy way to dump the response data from a TTURLRequest? I'm getting a server side error and I'd like to be able to quickly log the response in the console without having to tail the server logs. I'm using Three20's TTURLRequest in conjunction with TTURLJSONResponse, and so far I haven't been able to view that data easily unless the response is a JSON string. Any suggestions? Thanks!
Try to print the NSERROR
NSData *returnData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error];