Permalink
Browse files

#39 Changes to MGTwitterEngine to provide fuller error messages.

* Lets clients check for rate-limiting headers and possibly provide more informative error messages to users.
* Pass back the response body when available
* Updated the README to describe the changes to the NSError passed into requestFailed:withError:
  • Loading branch information...
1 parent 2cfc84a commit c1d314e7f97365914f98b1b882fc16c84a0c943f @jabley jabley committed with alexrepty Jul 16, 2010
Showing with 35 additions and 16 deletions.
  1. +28 −15 MGTwitterEngine.m
  2. +3 −0 MGTwitterHTTPURLConnection.h
  3. +3 −0 MGTwitterHTTPURLConnection.m
  4. +1 −1 README.txt
View
@@ -976,22 +976,10 @@ - (void)connection:(MGTwitterHTTPURLConnection *)connection didReceiveResponse:(
// Get response code.
NSHTTPURLResponse *resp = (NSHTTPURLResponse *)response;
+ [connection setResponse:resp];
NSInteger statusCode = [resp statusCode];
- if (statusCode >= 400) {
- // Assume failure, and report to delegate.
- NSError *error = [NSError errorWithDomain:@"HTTP" code:statusCode userInfo:nil];
- if ([self _isValidDelegateForSelector:@selector(requestFailed:withError:)])
- [_delegate requestFailed:[connection identifier] withError:error];
-
- // Destroy the connection.
- [connection cancel];
- NSString *connectionIdentifier = [connection identifier];
- [_connections removeObjectForKey:connectionIdentifier];
- if ([self _isValidDelegateForSelector:@selector(connectionFinished:)])
- [_delegate connectionFinished:connectionIdentifier];
-
- } else if (statusCode == 304 || [connection responseType] == MGTwitterGeneric) {
+ if (statusCode == 304 || [connection responseType] == MGTwitterGeneric) {
// Not modified, or generic success.
if ([self _isValidDelegateForSelector:@selector(requestSucceeded:)])
[_delegate requestSucceeded:[connection identifier]];
@@ -1048,7 +1036,32 @@ - (void)connection:(MGTwitterHTTPURLConnection *)connection didFailWithError:(NS
- (void)connectionDidFinishLoading:(MGTwitterHTTPURLConnection *)connection
{
- NSString *connID = nil;
+
+ NSInteger statusCode = [[connection response] statusCode];
+
+ if (statusCode >= 400) {
+ // Assume failure, and report to delegate.
+ NSData *receivedData = [connection data];
+ NSString *body = [receivedData length] ? [NSString stringWithUTF8String:[receivedData bytes]] : @"";
+
+ NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ [connection response], @"response",
+ body, @"body",
+ nil];
+ NSError *error = [NSError errorWithDomain:@"HTTP" code:statusCode userInfo:userInfo];
+ if ([self _isValidDelegateForSelector:@selector(requestFailed:withError:)])
+ [_delegate requestFailed:[connection identifier] withError:error];
+
+ // Destroy the connection.
+ [connection cancel];
+ NSString *connectionIdentifier = [connection identifier];
+ [_connections removeObjectForKey:connectionIdentifier];
+ if ([self _isValidDelegateForSelector:@selector(connectionFinished:)])
+ [_delegate connectionFinished:connectionIdentifier];
+ return;
+ }
+
+ NSString *connID = nil;
MGTwitterResponseType responseType = 0;
connID = [connection identifier];
responseType = [connection responseType];
@@ -18,6 +18,7 @@
MGTwitterResponseType _responseType; // type of response data expected (if successful)
NSString *_identifier;
NSURL *_URL; // the URL used for the connection (needed as a base URL when parsing with libxml)
+ NSHTTPURLResponse * _response; // the response.
}
// Initializer
@@ -36,4 +37,6 @@
- (MGTwitterResponseType)responseType;
- (NSString *)description;
+@property (nonatomic, retain) NSHTTPURLResponse *response;
+
@end
@@ -28,6 +28,8 @@ -(void)prepare{
@implementation MGTwitterHTTPURLConnection
+@synthesize response = _response;
+
#pragma mark Initializer
@@ -51,6 +53,7 @@ - (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate
- (void)dealloc
{
+ [_response release];
[_data release];
[_identifier release];
[_URL release];
View
@@ -75,7 +75,7 @@ Sometimes, of course, requests will fail - that's just how life is. In the unlik
It's far more common however that the connection itself will go ahead just fine, but there will be an error on Twitter's side, either due to technical difficulties, or because there was something wrong with your request (e.g. you entered the wrong username and password, or you tried to get info on a user that doesn't exist, or some such thing). The specific error conditions are mostly documented in the Twitter API documentation online.
-In these cases you'll receive a call to requestFailed:withError: which will include an NSError object detailing the error. Twitter usually returns meaningful HTTP error codes (like 404 for 'user not found', etc), and in that case the -domain of the NSError will be "HTTP" and the -code will be the relevant HTTP status code. This makes it really, really easy to know what's happening with your connections.
+In these cases you'll receive a call to requestFailed:withError: which will include an NSError object detailing the error. Twitter usually returns meaningful HTTP error codes (like 404 for 'user not found', etc), and in that case the -domain of the NSError will be "HTTP" and the -code will be the relevant HTTP status code. The userInfo of the NSError will contain a key "body" that may contain the response body and "response" which will contain the NSHTTPURLResponse. This makes it really, really easy to know what's happening with your connections.

0 comments on commit c1d314e

Please sign in to comment.