Add configurable error parsing to the object mapper.

This commit is contained in:
Jeremy Ellison
2010-10-14 12:51:12 -04:00
parent 069978ec07
commit 7c01d54fa3
3 changed files with 36 additions and 14 deletions

View File

@@ -101,20 +101,7 @@
[_delegate objectLoader:self didFailWithError:response.failureError];
return YES;
} else if ([response isError]) {
NSString* errorMessage = nil;
if ([response isJSON]) {
// TODO: Processing errors should be moved to a delegate to accommodate non-Rails services...
errorMessage = [[[response bodyAsJSON] valueForKey:@"errors"] componentsJoinedByString:@", "];
}
if (nil == errorMessage) {
errorMessage = [response bodyAsString];
}
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
errorMessage, NSLocalizedDescriptionKey,
nil];
NSError *error = [NSError errorWithDomain:RKRestKitErrorDomain code:RKObjectLoaderRemoteSystemError userInfo:userInfo];
[_delegate objectLoader:self didFailWithError:error];
[_delegate objectLoader:self didFailWithError:[_mapper parseErrorFromString:[response bodyAsString]]];
return YES;
}

View File

@@ -26,6 +26,8 @@ typedef enum {
NSArray* _dateFormats;
NSTimeZone* _remoteTimeZone;
NSTimeZone* _localTimeZone;
NSString* _errorsKeyPath;
NSString* _errorsConcatenationString;
}
/**
@@ -56,6 +58,16 @@ typedef enum {
*/
@property(nonatomic, retain) NSTimeZone* localTimeZone;
/*
* This defines the key path to look for errors in a string. defaults to @"errors"
*/
@property (nonatomic, copy) NSString* errorsKeyPath;
/*
* This string is used to concatenate the errors returned in a string. defaults to @", "
*/
@property (nonatomic, copy) NSString* errorsConcatenationString;
/**
* Register a mapping for a given class for an XML element with the given tag name
* will blow up if the class does not respond to elementToPropertyMappings and elementToRelationshipMappings
@@ -72,6 +84,12 @@ typedef enum {
*/
- (id)mapFromString:(NSString*)string;
/**
* Digests a string (such as an error response body) in to an NSError.
* It should only be called for a string you know contains an error.
*/
- (NSError*)parseErrorFromString:(NSString*)string;
/**
* Sets the properties and relationships serialized in the string into the model instance
* provided

View File

@@ -13,6 +13,7 @@
#import "RKObjectMapper.h"
#import "NSDictionary+RKAdditions.h"
#import "RKJSONParser.h"
#import "Errors.h"
// Default format string for date and time objects from Rails
// TODO: Rails specifics should probably move elsewhere...
@@ -47,6 +48,8 @@ static const NSString* kRKModelMapperMappingFormatParserKey = @"RKMappingFormatP
@synthesize dateFormats = _dateFormats;
@synthesize remoteTimeZone = _remoteTimeZone;
@synthesize localTimeZone = _localTimeZone;
@synthesize errorsKeyPath = _errorsKeyPath;
@synthesize errorsConcatenationString = _errorsConcatenationString;
///////////////////////////////////////////////////////////////////////////////
// public
@@ -59,6 +62,8 @@ static const NSString* kRKModelMapperMappingFormatParserKey = @"RKMappingFormatP
self.dateFormats = [NSArray arrayWithObjects:kRKModelMapperRailsDateTimeFormatString, kRKModelMapperRailsDateFormatString, nil];
self.remoteTimeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
self.localTimeZone = [NSTimeZone localTimeZone];
self.errorsKeyPath = @"errors";
self.errorsConcatenationString = @", ";
}
return self;
}
@@ -67,6 +72,8 @@ static const NSString* kRKModelMapperMappingFormatParserKey = @"RKMappingFormatP
[_elementToClassMappings release];
[_inspector release];
[_dateFormats release];
[_errorsKeyPath release];
[_errorsConcatenationString release];
[super dealloc];
}
@@ -101,6 +108,16 @@ static const NSString* kRKModelMapperMappingFormatParserKey = @"RKMappingFormatP
return result;
}
- (NSError*)parseErrorFromString:(NSString*)string {
NSString* errorMessage = [[[self parseString:string] valueForKeyPath:_errorsKeyPath] componentsJoinedByString:_errorsConcatenationString];
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
errorMessage, NSLocalizedDescriptionKey,
nil];
NSError *error = [NSError errorWithDomain:RKRestKitErrorDomain code:RKObjectLoaderRemoteSystemError userInfo:userInfo];
return error;
}
- (id)mapFromString:(NSString*)string toClass:(Class)class keyPath:(NSString*)keyPath {
id object = [self parseString:string];
if (keyPath) {