Skip to content

Commit

Permalink
provide default implementation for ReactHostDelegate.handleInstanceEx…
Browse files Browse the repository at this point in the history
…ception() (facebook#45521)

Summary:
Pull Request resolved: facebook#45521

[ReactHostDelegate.handleInstanceException()](https://github.com/facebook/react-native/blob/a6f5e5adebed3d9da411f99548e2d8ce96636e16/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultReactHostDelegate.kt#L48) is a no-op so providing a default implementation for this.
As a simplified solution, just throw a `RuntimeException` (on non-debug bulid) in this case. Below is the justification.

1) We may want to consider using `ExceptionsManagerModule` TurboModule in OSS to report the exception but current implementation  just [throws JavaScriptException](https://github.com/facebook/react-native/blob/a6f5e5adebed3d9da411f99548e2d8ce96636e16/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/ExceptionsManagerModule.java#L67) when it is fatal

2) If the exception happens during ReactInstance initialization then we may not have Turbo Module initialized and may not be able to access it. While we might want to fix how this works in longer term but for now just throw an Exception and let the app handle it.

3) In debug build, `DevSupportManager` is called before `handleInstanceException()` which would display a RedBox so don't throw when it is a debug build.

So it seems to best for now to just throw an exception so it can be handled by the app than silently ignoring it.

Changelog:
[Android][Added] - provide default implementation for ReactHostDelegate.handleInstanceException()

Reviewed By: javache

Differential Revision: D59847543
  • Loading branch information
alanleedev authored and facebook-github-bot committed Jul 29, 2024
1 parent e92ae77 commit 8376299
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ public class DefaultReactHostDelegate(
override val jsRuntimeFactory: JSRuntimeFactory = HermesInstance(),
override val bindingsInstaller: BindingsInstaller? = null,
private val reactNativeConfig: ReactNativeConfig = ReactNativeConfig.DEFAULT_CONFIG,
private val exceptionHandler: (Exception) -> Unit = {},
private val exceptionHandler: (Exception) -> Unit = {
throw RuntimeException("Unrecoverable React Native error", it)
},
override val turboModuleManagerDelegateBuilder: ReactPackageTurboModuleManagerDelegate.Builder
) : ReactHostDelegate {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,22 +63,4 @@ public interface ReactHostDelegate {
* parameter.
*/
public fun getReactNativeConfig(): ReactNativeConfig

@UnstableReactNativeAPI
public class ReactHostDelegateBase(
override val jsMainModulePath: String,
override val jsBundleLoader: JSBundleLoader,
override val jsRuntimeFactory: JSRuntimeFactory,
override val turboModuleManagerDelegateBuilder:
ReactPackageTurboModuleManagerDelegate.Builder,
override val reactPackages: List<ReactPackage> = emptyList(),
override val bindingsInstaller: BindingsInstaller? = null,
private val reactNativeConfig: ReactNativeConfig = ReactNativeConfig.DEFAULT_CONFIG,
private val exceptionHandler: (error: Exception) -> Unit = {}
) : ReactHostDelegate {

override fun getReactNativeConfig(): ReactNativeConfig = reactNativeConfig

override fun handleInstanceException(error: Exception): Unit = exceptionHandler(error)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -470,8 +470,9 @@ public TaskInterface<Void> reload(String reason) {
final Exception ex = task.getError();
if (mUseDevSupport) {
mDevSupportManager.handleException(ex);
} else {
mReactHostDelegate.handleInstanceException(ex);
}
mReactHostDelegate.handleInstanceException(ex);
return getOrCreateDestroyTask("Reload failed", ex);
}

Expand Down Expand Up @@ -806,9 +807,10 @@ DefaultHardwareBackBtnHandler getDefaultBackButtonHandler() {

if (mUseDevSupport) {
mDevSupportManager.handleException(e);
} else {
mReactHostDelegate.handleInstanceException(e);
}
destroy(method, e);
mReactHostDelegate.handleInstanceException(e);
}

/**
Expand Down Expand Up @@ -896,7 +898,12 @@ private Task<Void> getOrCreateStartTask() {
.continueWithTask(
(task) -> {
if (task.isFaulted()) {
mReactHostDelegate.handleInstanceException(task.getError());
Exception ex = task.getError();
if (mUseDevSupport) {
mDevSupportManager.handleException(ex);
} else {
mReactHostDelegate.handleInstanceException(ex);
}
// Wait for destroy to finish
return getOrCreateDestroyTask(
"getOrCreateStartTask() failure: " + task.getError().getMessage(),
Expand Down

0 comments on commit 8376299

Please sign in to comment.