From 9799c215cb0da862ea6e7d542ce82b9768a5e1a0 Mon Sep 17 00:00:00 2001 From: Tadeu Zagallo Date: Tue, 14 Jul 2015 16:11:42 -0700 Subject: [PATCH] [ReactNative] Add JS errors handling to iOS Summary: Every once in a while a guard is forgotten somewhere and the redbox is gone. I want to remove the guards, but for that the stack traces have to be symbolicated on the native side. So for now it just adds yet another check, in case a guard is missing on JS. --- React/Base/RCTBatchedBridge.m | 41 ++++++++++++++++++++--------------- React/Base/RCTRedBox.h | 1 + React/Base/RCTRedBox.m | 6 +++++ 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/React/Base/RCTBatchedBridge.m b/React/Base/RCTBatchedBridge.m index b1bb6cf1a..49cf49bb0 100644 --- a/React/Base/RCTBatchedBridge.m +++ b/React/Base/RCTBatchedBridge.m @@ -239,7 +239,11 @@ RCT_NOT_IMPLEMENTED(-initWithBundleURL:(__unused NSURL *)bundleURL dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [_javaScriptExecutor injectJSONText:configJSON asGlobalObjectNamed:@"__fbBatchedBridgeConfig" callback: - ^(__unused id err) { + ^(NSError *error) { + if (error) { + [[RCTRedBox sharedInstance] showError:error]; + } + dispatch_semaphore_signal(semaphore); }]; @@ -302,22 +306,21 @@ RCT_NOT_IMPLEMENTED(-initWithBundleURL:(__unused NSURL *)bundleURL [self enqueueApplicationScript:script url:bundleURL onComplete:^(NSError *loadError) { - if (!loadError) { - - /** - * Register the display link to start sending js calls after everything - * is setup - */ - NSRunLoop *targetRunLoop = [_javaScriptExecutor isKindOfClass:[RCTContextExecutor class]] ? [NSRunLoop currentRunLoop] : [NSRunLoop mainRunLoop]; - [_jsDisplayLink addToRunLoop:targetRunLoop forMode:NSRunLoopCommonModes]; - - [[NSNotificationCenter defaultCenter] postNotificationName:RCTJavaScriptDidLoadNotification - object:_parentBridge - userInfo:@{ @"bridge": self }]; - } else { - [[RCTRedBox sharedInstance] showErrorMessage:[loadError localizedDescription] - withDetails:[loadError localizedFailureReason]]; + if (loadError) { + [[RCTRedBox sharedInstance] showError:loadError]; + return; } + + /** + * Register the display link to start sending js calls after everything + * is setup + */ + NSRunLoop *targetRunLoop = [_javaScriptExecutor isKindOfClass:[RCTContextExecutor class]] ? [NSRunLoop currentRunLoop] : [NSRunLoop mainRunLoop]; + [_jsDisplayLink addToRunLoop:targetRunLoop forMode:NSRunLoopCommonModes]; + + [[NSNotificationCenter defaultCenter] postNotificationName:RCTJavaScriptDidLoadNotification + object:_parentBridge + userInfo:@{ @"bridge": self }]; }]; } }]; @@ -527,7 +530,11 @@ RCT_NOT_IMPLEMENTED(-initWithBundleURL:(__unused NSURL *)bundleURL [[NSNotificationCenter defaultCenter] postNotificationName:RCTEnqueueNotification object:nil userInfo:nil]; - RCTJavaScriptCallback processResponse = ^(id json, __unused NSError *error) { + RCTJavaScriptCallback processResponse = ^(id json, NSError *error) { + if (error) { + [[RCTRedBox sharedInstance] showError:error]; + } + if (!self.isValid) { return; } diff --git a/React/Base/RCTRedBox.h b/React/Base/RCTRedBox.h index 7a1f51f36..168772a91 100644 --- a/React/Base/RCTRedBox.h +++ b/React/Base/RCTRedBox.h @@ -13,6 +13,7 @@ + (instancetype)sharedInstance; +- (void)showError:(NSError *)error; - (void)showErrorMessage:(NSString *)message; - (void)showErrorMessage:(NSString *)message withDetails:(NSString *)details; - (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack; diff --git a/React/Base/RCTRedBox.m b/React/Base/RCTRedBox.m index 8e85c0ca2..a707c6532 100644 --- a/React/Base/RCTRedBox.m +++ b/React/Base/RCTRedBox.m @@ -283,6 +283,11 @@ RCT_NOT_IMPLEMENTED(-initWithCoder:(NSCoder *)aDecoder) _nextBackgroundColor = color; } +- (void)showError:(NSError *)error +{ + [self showErrorMessage:error.localizedDescription withDetails:error.localizedFailureReason]; +} + - (void)showErrorMessage:(NSString *)message { [self showErrorMessage:message withStack:nil showIfHidden:YES]; @@ -342,6 +347,7 @@ RCT_NOT_IMPLEMENTED(-initWithCoder:(NSCoder *)aDecoder) @implementation RCTRedBox + (instancetype)sharedInstance { return nil; } +- (void)showError:(NSError *)message {} - (void)showErrorMessage:(NSString *)message {} - (void)showErrorMessage:(NSString *)message withDetails:(NSString *)details {} - (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack {}