From accf4b8cd0d2e6b8342607b8bbe414621fe9f29c Mon Sep 17 00:00:00 2001 From: Neil Sarkar Date: Sat, 22 Oct 2016 14:47:21 +0100 Subject: [PATCH 1/3] Allow serializing underlying NSError objects, closes #10506 --- React/Base/RCTUtils.m | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/React/Base/RCTUtils.m b/React/Base/RCTUtils.m index ff50a647994acd..264ae95a0077f5 100644 --- a/React/Base/RCTUtils.m +++ b/React/Base/RCTUtils.m @@ -413,18 +413,28 @@ BOOL RCTClassOverridesInstanceMethod(Class cls, SEL selector) { NSString *errorMessage; NSArray *stackTrace = [NSThread callStackSymbols]; + NSMutableDictionary *userInfo; NSMutableDictionary *errorInfo = [NSMutableDictionary dictionaryWithObject:stackTrace forKey:@"nativeStackIOS"]; if (error) { errorMessage = error.localizedDescription ?: @"Unknown error from a native module"; errorInfo[@"domain"] = error.domain ?: RCTErrorDomain; + if (error.userInfo) { + userInfo = [error.userInfo mutableCopy]; + if (userInfo != nil && userInfo[NSUnderlyingErrorKey] != nil) { + NSError *underlyingError = error.userInfo[NSUnderlyingErrorKey]; + NSString *underlyingCode = [NSString stringWithFormat:@"%d", (int)underlyingError.code]; + userInfo[NSUnderlyingErrorKey] = RCTJSErrorFromCodeMessageAndNSError(underlyingCode, @"underlying error", underlyingError); + } + } } else { errorMessage = @"Unknown error from a native module"; errorInfo[@"domain"] = RCTErrorDomain; + userInfo = nil; } errorInfo[@"code"] = code ?: RCTErrorUnspecified; - errorInfo[@"userInfo"] = RCTNullIfNil(error.userInfo); + errorInfo[@"userInfo"] = RCTNullIfNil(userInfo); // Allow for explicit overriding of the error message errorMessage = message ?: errorMessage; From 3e6510d2972bb51fdb2c38f1854296539185092a Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Sat, 22 Oct 2016 06:30:43 -0700 Subject: [PATCH 2/3] Update all the babel things Reviewed By: bestander Differential Revision: D4051237 fbshipit-source-id: ebe919d336b8e4f5d58ef12186026aac37cbc7f2 --- package.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 1597e740a2b648..5da21ebc09f53b 100644 --- a/package.json +++ b/package.json @@ -137,19 +137,19 @@ "absolute-path": "^0.0.0", "art": "^0.10.0", "async": "^2.0.1", - "babel-core": "^6.10.4", - "babel-generator": "^6.14.0", + "babel-core": "^6.17.0", + "babel-generator": "^6.17.0", "babel-plugin-external-helpers": "^6.8.0", - "babel-plugin-syntax-trailing-function-commas": "^6.5.0", - "babel-plugin-transform-flow-strip-types": "^6.6.5", - "babel-plugin-transform-object-rest-spread": "^6.6.5", - "babel-polyfill": "^6.9.1", - "babel-preset-es2015-node": "^6.1.0", - "babel-preset-fbjs": "^2.0.0", + "babel-plugin-syntax-trailing-function-commas": "^6.13.0", + "babel-plugin-transform-flow-strip-types": "^6.14.0", + "babel-plugin-transform-object-rest-spread": "^6.16.0", + "babel-polyfill": "^6.16.0", + "babel-preset-es2015-node": "^6.1.1", + "babel-preset-fbjs": "^2.1.0", "babel-preset-react-native": "^1.9.0", - "babel-register": "^6.6.0", - "babel-types": "^6.6.4", - "babylon": "^6.8.2", + "babel-register": "^6.16.3", + "babel-types": "^6.16.0", + "babylon": "^6.13.0", "base64-js": "^1.1.2", "bser": "^1.0.2", "chalk": "^1.1.1", From 308f85475282eb7eb88ef2faa3da4f6777235294 Mon Sep 17 00:00:00 2001 From: Neil Sarkar Date: Wed, 26 Oct 2016 02:27:13 +0100 Subject: [PATCH 3/3] Add unit test for stringifying nested error --- .../UIExplorerUnitTests/RCTJSONTests.m | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Examples/UIExplorer/UIExplorerUnitTests/RCTJSONTests.m b/Examples/UIExplorer/UIExplorerUnitTests/RCTJSONTests.m index acacc3a34c4638..bbbe194c5e9867 100644 --- a/Examples/UIExplorer/UIExplorerUnitTests/RCTJSONTests.m +++ b/Examples/UIExplorer/UIExplorerUnitTests/RCTJSONTests.m @@ -42,6 +42,25 @@ - (void)testEncodingString XCTAssertEqualObjects(json, RCTJSONStringify(text, NULL)); } +- (void)testEncodingNSError +{ + NSError *underlyingError = [NSError errorWithDomain:@"underlyingDomain" code:421 userInfo:nil]; + NSError *err = [NSError errorWithDomain:@"domain" code:68 userInfo:@{@"NSUnderlyingError": underlyingError}]; + + // An assertion on the full object would be too brittle since it contains an iOS stack trace + // so we are relying on the behavior of RCTJSONParse, which is tested below. + NSDictionary *jsonObject = RCTJSErrorFromNSError(err); + NSString *jsonString = RCTJSONStringify(jsonObject, NULL); + NSDictionary *json = RCTJSONParse(jsonString, NULL); + XCTAssertEqualObjects(json[@"code"], @"EDOMAIN68"); + XCTAssertEqualObjects(json[@"message"], @"The operation couldn’t be completed. (domain error 68.)"); + XCTAssertEqualObjects(json[@"domain"], @"domain"); + XCTAssertEqualObjects(json[@"userInfo"][@"NSUnderlyingError"][@"code"], @"421"); + XCTAssertEqualObjects(json[@"userInfo"][@"NSUnderlyingError"][@"message"], @"underlying error"); + XCTAssertEqualObjects(json[@"userInfo"][@"NSUnderlyingError"][@"domain"], @"underlyingDomain"); +} + + - (void)testDecodingObject { NSDictionary *obj = @{@"foo": @"bar"};