[React Native] Update native error callback handling

Summary:
This introduces a new `RCTResponseErrorBlock` block type that allows a bridge module writer to call it with an `NSError` instance rather than a dictionary.
This commit is contained in:
Alex Akers
2015-07-07 08:47:23 -07:00
parent 66d3f3c616
commit 3c541ca540
6 changed files with 39 additions and 18 deletions

View File

@@ -19,6 +19,12 @@
*/
typedef void (^RCTResponseSenderBlock)(NSArray *response);
/**
* The type of a block that is capable of sending an error response to a
* bridged operation. Use this for returning error information to JS.
*/
typedef void (^RCTResponseErrorBlock)(NSError *error);
/**
* Block that bridge modules use to resolve the JS promise waiting for a result.
* Nil results are supported and are converted to JS's undefined value.

View File

@@ -174,6 +174,22 @@ case _value: { \
}
} else if ([argumentName isEqualToString:@"RCTResponseSenderBlock"]) {
addBlockArgument();
} else if ([argumentName isEqualToString:@"RCTResponseErrorBlock"]) {
RCT_ARG_BLOCK(
if (RCT_DEBUG && json && ![json isKindOfClass:[NSNumber class]]) {
RCTLogError(@"Argument %tu (%@) of %@.%@ should be a number", index,
json, RCTBridgeModuleNameForClass(_moduleClass), _JSMethodName);
return;
}
// Marked as autoreleasing, because NSInvocation doesn't retain arguments
__autoreleasing id value = (json ? ^(NSError *error) {
[bridge _invokeAndProcessModule:@"BatchedBridge"
method:@"invokeCallbackAndReturnFlushedQueue"
arguments:@[json, @[RCTJSErrorFromNSError(error)]]];
} : ^(__unused NSError *error) {});
)
} else if ([argumentName isEqualToString:@"RCTPromiseResolveBlock"]) {
RCTAssert(i == numberOfArguments - 2,
@"The RCTPromiseResolveBlock must be the second to last parameter in -[%@ %@]",

View File

@@ -45,7 +45,6 @@ RCT_EXTERN BOOL RCTClassOverridesClassMethod(Class cls, SEL selector);
RCT_EXTERN BOOL RCTClassOverridesInstanceMethod(Class cls, SEL selector);
// Creates a standardized error object
// TODO(#6472857): create NSErrors and automatically convert them over the bridge.
RCT_EXTERN NSDictionary *RCTMakeError(NSString *message, id toStringify, NSDictionary *extraData);
RCT_EXTERN NSDictionary *RCTMakeAndLogError(NSString *message, id toStringify, NSDictionary *extraData);
@@ -55,7 +54,7 @@ RCT_EXTERN BOOL RCTRunningInTestEnvironment(void);
// Return YES if image has an alpha component
RCT_EXTERN BOOL RCTImageHasAlpha(CGImageRef image);
// Create an NSError in the NCTErrorDomain
// Create an NSError in the RCTErrorDomain
RCT_EXTERN NSError *RCTErrorWithMessage(NSString *message);
// Convert nil values to NSNull, and vice-versa

View File

@@ -231,12 +231,11 @@ BOOL RCTClassOverridesInstanceMethod(Class cls, SEL selector)
NSDictionary *RCTMakeError(NSString *message, id toStringify, NSDictionary *extraData)
{
if (toStringify) {
message = [NSString stringWithFormat:@"%@%@", message, toStringify];
}
NSMutableDictionary *error = [@{@"message": message} mutableCopy];
if (extraData) {
[error addEntriesFromDictionary:extraData];
message = [message stringByAppendingString:[toStringify description]];
}
NSMutableDictionary *error = [NSMutableDictionary dictionaryWithDictionary:extraData];
error[@"message"] = message;
return error;
}