diff --git a/Libraries/RCTTest/RCTTestModule.m b/Libraries/RCTTest/RCTTestModule.m index 0692543e755a54..a889b8522a4e79 100644 --- a/Libraries/RCTTest/RCTTestModule.m +++ b/Libraries/RCTTest/RCTTestModule.m @@ -62,7 +62,7 @@ - (dispatch_queue_t)methodQueue RCT_REMAP_METHOD(shouldReject, shouldReject_resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { - reject(nil); + reject(nil, nil, nil); } RCT_EXPORT_METHOD(markTestCompleted) diff --git a/React/Base/RCTBridgeModule.h b/React/Base/RCTBridgeModule.h index 39c7acad4aee9c..067ecb4927d129 100644 --- a/React/Base/RCTBridgeModule.h +++ b/React/Base/RCTBridgeModule.h @@ -37,7 +37,7 @@ typedef void (^RCTPromiseResolveBlock)(id result); * The error may be nil but it is preferable to pass an NSError object for more * precise error messages. */ -typedef void (^RCTPromiseRejectBlock)(NSError *error); +typedef void (^RCTPromiseRejectBlock)(NSString *code, NSString *message, NSError *error); /** * This constant can be returned from +methodQueue to force module diff --git a/React/Base/RCTModuleMethod.m b/React/Base/RCTModuleMethod.m index 8f54f2d9e44a22..0a6cd9390e6e87 100644 --- a/React/Base/RCTModuleMethod.m +++ b/React/Base/RCTModuleMethod.m @@ -335,8 +335,8 @@ - (void)processMethodSignature return NO; } - RCT_BLOCK_ARGUMENT(^(NSError *error) { - NSDictionary *errorJSON = RCTJSErrorFromNSError(error); + RCT_BLOCK_ARGUMENT(^(NSString *code, NSString *message, NSError *error) { + NSDictionary *errorJSON = RCTJSErrorFromCodeMessageAndNSError(code, message, error); [bridge enqueueCallback:json args:@[errorJSON]]; }); ) diff --git a/React/Base/RCTUtils.h b/React/Base/RCTUtils.h index 5e6815c4e03fba..36383e8c61ab20 100644 --- a/React/Base/RCTUtils.h +++ b/React/Base/RCTUtils.h @@ -52,6 +52,10 @@ RCT_EXTERN BOOL RCTClassOverridesInstanceMethod(Class cls, SEL selector); RCT_EXTERN NSDictionary *RCTMakeError(NSString *message, id toStringify, NSDictionary *extraData); RCT_EXTERN NSDictionary *RCTMakeAndLogError(NSString *message, id toStringify, NSDictionary *extraData); RCT_EXTERN NSDictionary *RCTJSErrorFromNSError(NSError *error); +RCT_EXTERN NSDictionary *RCTJSErrorFromCodeMessageAndNSError(NSString *code, NSString *message, NSError *error); + +// The default error code that will be sent in the .code value of the Error object to js +RCT_EXTERN NSString *const RCTErrorUnspecified; // Returns YES if React is running in a test environment RCT_EXTERN BOOL RCTRunningInTestEnvironment(void); diff --git a/React/Base/RCTUtils.m b/React/Base/RCTUtils.m index e6ebdb8061b353..cf0d8b8b00e48f 100644 --- a/React/Base/RCTUtils.m +++ b/React/Base/RCTUtils.m @@ -21,6 +21,8 @@ #import "RCTLog.h" +NSString *const RCTErrorUnspecified = @"EUNSPECIFIED"; + NSString *RCTJSONStringify(id jsonObject, NSError **error) { static SEL JSONKitSelector = NULL; @@ -313,27 +315,34 @@ BOOL RCTClassOverridesInstanceMethod(Class cls, SEL selector) return error; } -// TODO: Can we just replace RCTMakeError with this function instead? NSDictionary *RCTJSErrorFromNSError(NSError *error) +{ + return RCTJSErrorFromCodeMessageAndNSError(RCTErrorUnspecified, nil, error); +} + +// TODO: Can we just replace RCTMakeError with this function instead? +NSDictionary *RCTJSErrorFromCodeMessageAndNSError(NSString *code, NSString *message, NSError *error) { NSString *errorMessage; NSArray *stackTrace = [NSThread callStackSymbols]; NSMutableDictionary *errorInfo = - [NSMutableDictionary dictionaryWithObject:stackTrace forKey:@"nativeStackIOS"]; + [NSMutableDictionary dictionaryWithObject:stackTrace forKey:@"nativeStackIOS"]; if (error) { errorMessage = error.localizedDescription ?: @"Unknown error from a native module"; errorInfo[@"domain"] = error.domain ?: RCTErrorDomain; - errorInfo[@"code"] = @(error.code); } else { errorMessage = @"Unknown error from a native module"; errorInfo[@"domain"] = RCTErrorDomain; - errorInfo[@"code"] = @-1; } + errorInfo[@"code"] = code ?: RCTErrorUnspecified; + // Allow for explicit overriding of the error message + errorMessage = message ?: errorMessage; return RCTMakeError(errorMessage, nil, errorInfo); } + BOOL RCTRunningInTestEnvironment(void) { static BOOL isTestEnvironment = NO;