Skip to content

Commit dfd445c

Browse files
NickGerlemanfacebook-github-bot
authored andcommitted
Terminate instead of throwing if TurboModule callback double-called (#37570)
Summary: Pull Request resolved: #37570 If a TM calls a completion callback, or resolves or rejects a promise multiple times, a C++ exception is thrown. For an in the wild crash, we are getting this signal as: 1. `libdispatch` calls std::terminate while pumping a thread's message queue 2. The hooked FB app termination handler is called, which introspects for the currently handled exception 4. We are handling this TurboModule C++ exception being thrown, suggesting `libdispatch` termination may be due to catching this C++ exception which was not otherwise handled 4. We have by this point lost the stack trace of the code invoking the callback I think if we change the timing of `abort()` to when the callback is called, we might be able to preserve the stack trace of module code calling the callback. Reviewed By: javache Differential Revision: D46175685 fbshipit-source-id: 680aa9aa5e4ca6d8dd04dfe34ec870b86c7640ef
1 parent 1691801 commit dfd445c

File tree

5 files changed

+8
-4
lines changed

5 files changed

+8
-4
lines changed

packages/react-native/ReactCommon/react/nativemodule/core/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ target_include_directories(react_nativemodule_core
3232
target_link_libraries(react_nativemodule_core
3333
fbjni
3434
folly_runtime
35+
glog
3536
jsi
3637
react_bridging
3738
react_debug

packages/react-native/ReactCommon/react/nativemodule/core/ReactCommon/TurboCxxModule.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <vector>
1111

1212
#include <ReactCommon/TurboModuleUtils.h>
13+
#include <glog/logging.h>
1314
#include <jsi/JSIDynamic.h>
1415

1516
using namespace facebook;
@@ -24,7 +25,7 @@ CxxModule::Callback makeTurboCxxModuleCallback(
2425
return [weakWrapper,
2526
wrapperWasCalled = false](std::vector<folly::dynamic> args) mutable {
2627
if (wrapperWasCalled) {
27-
throw std::runtime_error("callback arg cannot be called more than once");
28+
LOG(FATAL) << "callback arg cannot be called more than once";
2829
}
2930

3031
auto strongWrapper = weakWrapper.lock();

packages/react-native/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <string>
1111

1212
#include <fbjni/fbjni.h>
13+
#include <glog/logging.h>
1314
#include <jsi/jsi.h>
1415

1516
#include <ReactCommon/TurboModule.h>
@@ -83,8 +84,7 @@ jni::local_ref<JCxxCallbackImpl::JavaPart> createJavaCallbackFromJSIFunction(
8384
callbackWrapperOwner = std::move(callbackWrapperOwner),
8485
wrapperWasCalled = false](folly::dynamic responses) mutable {
8586
if (wrapperWasCalled) {
86-
throw std::runtime_error(
87-
"Callback arg cannot be called more than once");
87+
LOG(FATAL) << "callback arg cannot be called more than once";
8888
}
8989

9090
auto strongWrapper = weakWrapper.lock();

packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/React-NativeModulesApple.podspec

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ Pod::Spec.new do |s|
4242

4343
s.source_files = "ReactCommon/**/*.{mm,cpp,h}"
4444

45+
s.dependency "glog"
4546
s.dependency "ReactCommon/turbomodule/core"
4647
s.dependency "ReactCommon/turbomodule/bridging"
4748
s.dependency "React-callinvoker"

packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.mm

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#import "RCTTurboModule.h"
99
#import "RCTBlockGuard.h"
1010

11+
#include <glog/logging.h>
1112
#import <objc/message.h>
1213
#import <objc/runtime.h>
1314
#import <atomic>
@@ -184,7 +185,7 @@ id convertJSIValueToObjCObject(jsi::Runtime &runtime, const jsi::Value &value, s
184185
BOOL __block wrapperWasCalled = NO;
185186
RCTResponseSenderBlock callback = ^(NSArray *responses) {
186187
if (wrapperWasCalled) {
187-
throw std::runtime_error("callback arg cannot be called more than once");
188+
LOG(FATAL) << "callback arg cannot be called more than once";
188189
}
189190

190191
auto strongWrapper = weakWrapper.lock();

0 commit comments

Comments
 (0)