Only handle the first javascript fatal error (#47783)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47783

After the first javascript fatal, the runtime starts tearing down. And it becomes invalid. So, subsequent js fatals will most likely be just noise. Let's filter them out.

This impacts bridgeless mode: both the javascript and c++ pipeline.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D66193194

fbshipit-source-id: 61a731850f7ac4f00bfac24e3260673bf94ba8ed
This commit is contained in:
Ramanpreet Nara
2024-11-21 14:09:08 -08:00
committed by Facebook GitHub Bot
parent 451ff70da4
commit c02e3b1c60
3 changed files with 38 additions and 9 deletions
@@ -121,6 +121,12 @@ function reportException(
const NativeExceptionsManager =
require('./NativeExceptionsManager').default;
if (NativeExceptionsManager) {
if (isFatal) {
if (global.RN$hasHandledFatalException?.()) {
return;
}
global.RN$notifyOfFatalException?.();
}
NativeExceptionsManager.reportException(data);
}
}
@@ -232,10 +232,6 @@ void JsErrorHandler::handleError(
if (!ReactNativeFeatureFlags::useAlwaysAvailableJSErrorHandling() &&
_isRuntimeReady) {
if (isFatal) {
_hasHandledFatalError = true;
}
try {
handleJSError(runtime, error, isFatal);
return;
@@ -382,7 +378,7 @@ void JsErrorHandler::handleErrorWithCppPipeline(
}
}
if (*shouldPreventDefault) {
if (*shouldPreventDefault || _hasHandledFatalError) {
return;
}
@@ -436,6 +436,37 @@ void ReactInstance::initializeRuntime(
return jsErrorHandler->isRuntimeReady();
}));
defineReadOnlyGlobal(
runtime,
"RN$hasHandledFatalException",
jsi::Function::createFromHostFunction(
runtime,
jsi::PropNameID::forAscii(runtime, "hasHandledFatalException"),
0,
[jsErrorHandler = jsErrorHandler_](
jsi::Runtime& /*runtime*/,
const jsi::Value& /*unused*/,
const jsi::Value* /*args*/,
size_t /*count*/) {
return jsErrorHandler->hasHandledFatalError();
}));
defineReadOnlyGlobal(
runtime,
"RN$notifyOfFatalException",
jsi::Function::createFromHostFunction(
runtime,
jsi::PropNameID::forAscii(runtime, "notifyOfFatalException"),
0,
[jsErrorHandler = jsErrorHandler_](
jsi::Runtime& /*runtime*/,
const jsi::Value& /*unused*/,
const jsi::Value* /*args*/,
size_t /*count*/) {
jsErrorHandler->notifyOfFatalError();
return jsi::Value::undefined();
}));
defineReadOnlyGlobal(
runtime,
"RN$inExceptionHandler",
@@ -475,10 +506,6 @@ void ReactInstance::initializeRuntime(
if (!ReactNativeFeatureFlags::
useAlwaysAvailableJSErrorHandling()) {
if (jsErrorHandler->isRuntimeReady()) {
if (isFatal) {
jsErrorHandler->notifyOfFatalError();
}
return jsi::Value(false);
}
}