Skip to content

Commit ea29ae1

Browse files
RSNarafacebook-github-bot
authored andcommitted
SurfaceRegistryBinding: Display RedBox when RN$SurfaceRegistry isn't available
Summary: SurfaceRegistryBinding::startSurface [checks whether global.RN$SurfaceRegistry binding is installed](https://www.internalfb.com/code/fbsource/[7040bef7d4fe43298c5f9dc1fef10f47ec396e79]/xplat/js/react-native-github/ReactCommon/react/renderer/uimanager/SurfaceRegistryBinding.cpp?lines=28-29). If not, control flow goes directly into the bridge path: [callFunctionOnModule](https://www.internalfb.com/code/fbsource/[7040bef7d4fe43298c5f9dc1fef10f47ec396e79]/xplat/js/react-native-github/ReactCommon/react/renderer/uimanager/SurfaceRegistryBinding.cpp?lines=40-46). callMethodOfModule [react_native_asserts, if the requested callable JS module isn't available](https://www.internalfb.com/code/fbsource/[7040bef7d4fe43298c5f9dc1fef10f47ec396e79]/xplat/js/react-native-github/ReactCommon/react/renderer/uimanager/bindingUtils.cpp?lines=29) on the batched bridge. This crashes the app. We could make this error experience better: 1. We shouldn't crash the app. 2. We should fail fast, and produce an error message that is more descriptive of the actual cause of the error. 3. We can leverage the RedBox infra to display this error on the screen. ## Fixes This diff modifies the gating inside SurfaceRegistryBinding. Now, in bridgeless mode, if global.RN$SurfaceRegistry isn't instaled, we'll display a RedBox instead, that shows what the error is. Changelog: [Internal] Reviewed By: sshic Differential Revision: D37223640 fbshipit-source-id: 8fbf57f5d9cf359046dc94f0a5f7d66624caee4e
1 parent 4967e50 commit ea29ae1

File tree

1 file changed

+28
-8
lines changed

1 file changed

+28
-8
lines changed

ReactCommon/react/renderer/uimanager/SurfaceRegistryBinding.cpp

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,19 @@ void SurfaceRegistryBinding::startSurface(
2525
parameters["initialProps"] = initalProps;
2626
parameters["fabric"] = true;
2727

28-
if (runtime.global().hasProperty(runtime, "RN$SurfaceRegistry")) {
29-
auto registry =
30-
runtime.global().getPropertyAsObject(runtime, "RN$SurfaceRegistry");
31-
auto method = registry.getPropertyAsFunction(runtime, "renderSurface");
28+
auto global = runtime.global();
29+
auto isBridgeless = global.hasProperty(runtime, "RN$Bridgeless") &&
30+
global.getProperty(runtime, "RN$Bridgeless").asBool();
3231

32+
if (isBridgeless) {
33+
if (!global.hasProperty(runtime, "RN$SurfaceRegistry")) {
34+
throw std::runtime_error(
35+
"SurfaceRegistryBinding::startSurface: Failed to start Surface \"" +
36+
moduleName + "\". global.RN$SurfaceRegistry was not installed.");
37+
}
38+
39+
auto registry = global.getPropertyAsObject(runtime, "RN$SurfaceRegistry");
40+
auto method = registry.getPropertyAsFunction(runtime, "renderSurface");
3341
method.call(
3442
runtime,
3543
{jsi::String::createFromUtf8(runtime, moduleName),
@@ -58,9 +66,18 @@ void SurfaceRegistryBinding::setSurfaceProps(
5866
parameters["initialProps"] = initalProps;
5967
parameters["fabric"] = true;
6068

61-
if (runtime.global().hasProperty(runtime, "RN$SurfaceRegistry")) {
62-
auto registry =
63-
runtime.global().getPropertyAsObject(runtime, "RN$SurfaceRegistry");
69+
auto global = runtime.global();
70+
auto isBridgeless = global.hasProperty(runtime, "RN$Bridgeless") &&
71+
global.getProperty(runtime, "RN$Bridgeless").asBool();
72+
73+
if (isBridgeless) {
74+
if (!global.hasProperty(runtime, "RN$SurfaceRegistry")) {
75+
throw std::runtime_error(
76+
"SurfaceRegistryBinding::setSurfaceProps: Failed to set Surface props for \"" +
77+
moduleName + "\". global.RN$SurfaceRegistry was not installed.");
78+
}
79+
80+
auto registry = global.getPropertyAsObject(runtime, "RN$SurfaceRegistry");
6481
auto method = registry.getPropertyAsFunction(runtime, "setSurfaceProps");
6582

6683
method.call(
@@ -83,7 +100,10 @@ void SurfaceRegistryBinding::stopSurface(
83100
jsi::Runtime &runtime,
84101
SurfaceId surfaceId) {
85102
auto global = runtime.global();
86-
if (global.hasProperty(runtime, "RN$Bridgeless")) {
103+
auto isBridgeless = global.hasProperty(runtime, "RN$Bridgeless") &&
104+
global.getProperty(runtime, "RN$Bridgeless").asBool();
105+
106+
if (isBridgeless) {
87107
if (!global.hasProperty(runtime, "RN$stopSurface")) {
88108
// ReactFabric module has not been loaded yet; there's no surface to stop.
89109
return;

0 commit comments

Comments
 (0)