diff --git a/packages/react-native/React/CoreModules/RCTRedBox.mm b/packages/react-native/React/CoreModules/RCTRedBox.mm index 822e17ab570..15cf2f023aa 100644 --- a/packages/react-native/React/CoreModules/RCTRedBox.mm +++ b/packages/react-native/React/CoreModules/RCTRedBox.mm @@ -274,7 +274,13 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder) - (void)reload { - [_actionDelegate reloadFromRedBoxController:self]; + if (_actionDelegate != nil) { + [_actionDelegate reloadFromRedBoxController:self]; + } else { + // In bridgeless mode `RCTRedBox` gets deallocated, we need to notify listeners anyway. + RCTTriggerReloadCommandListeners(@"Redbox"); + [self dismiss]; + } } - (void)showExtraDataViewController diff --git a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm index 6b9f987123c..38f17f96129 100644 --- a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm +++ b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm @@ -28,6 +28,8 @@ #import #import #import +#import +#import #import #import #import @@ -122,10 +124,17 @@ void RCTInstanceSetRuntimeDiagnosticFlags(NSString *flags) }]; } - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(_notifyEventDispatcherObserversOfEvent_DEPRECATED:) - name:@"RCTNotifyEventDispatcherObserversOfEvent_DEPRECATED" - object:nil]; + NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter]; + + [defaultCenter addObserver:self + selector:@selector(_notifyEventDispatcherObserversOfEvent_DEPRECATED:) + name:@"RCTNotifyEventDispatcherObserversOfEvent_DEPRECATED" + object:nil]; + + [defaultCenter addObserver:self + selector:@selector(didReceiveReloadCommand) + name:RCTTriggerReloadCommandNotification + object:nil]; [self _start]; } @@ -389,6 +398,24 @@ void RCTInstanceSetRuntimeDiagnosticFlags(NSString *flags) } } +- (void)handleBundleLoadingError:(NSError *)error +{ + if (!_valid) { + return; + } + + RCTRedBox *redBox = [_turboModuleManager moduleForName:"RedBox"]; + + RCTExecuteOnMainQueue(^{ + [[NSNotificationCenter defaultCenter] postNotificationName:RCTJavaScriptDidFailToLoadNotification + object:self + userInfo:@{@"error" : error}]; + [redBox showErrorMessage:[error localizedDescription]]; + + RCTFatal(error); + }); +} + - (void)_loadJSBundle:(NSURL *)sourceURL { #if RCT_DEV_MENU && __has_include() @@ -420,8 +447,7 @@ void RCTInstanceSetRuntimeDiagnosticFlags(NSString *flags) } if (error) { - // TODO(T91461138): Properly address bundle loading errors. - RCTLogError(@"RCTInstance: Error while loading bundle: %@", error); + [strongSelf handleBundleLoadingError:error]; [strongSelf invalidate]; return; } @@ -490,4 +516,9 @@ void RCTInstanceSetRuntimeDiagnosticFlags(NSString *flags) isFatal:errorMap.getBool(JSErrorHandlerKey::kIsFatal)]; } +- (void)didReceiveReloadCommand +{ + [self _loadJSBundle:[_bridgeModuleDecorator.bundleManager bundleURL]]; +} + @end