Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 21 additions & 18 deletions packages/react-native/Libraries/Core/ExceptionsManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,24 +141,27 @@ let inExceptionHandler = false;
* Logs exceptions to the (native) console and displays them
*/
function handleException(e: mixed, isFatal: boolean) {
let error: Error;
if (e instanceof Error) {
error = e;
} else {
// Workaround for reporting errors caused by `throw 'some string'`
// Unfortunately there is no way to figure out the stacktrace in this
// case, so if you ended up here trying to trace an error, look for
// `throw '<error message>'` somewhere in your codebase.
error = new SyntheticError(e);
}
try {
inExceptionHandler = true;
/* $FlowFixMe[class-object-subtyping] added when improving typing for this
* parameters */
// $FlowFixMe[incompatible-call]
reportException(error, isFatal, /*reportToConsole*/ true);
} finally {
inExceptionHandler = false;
// TODO(T196834299): We should really use a c++ turbomodule for this
if (!global.RN$handleException || !global.RN$handleException(e, isFatal)) {
let error: Error;
if (e instanceof Error) {
error = e;
} else {
// Workaround for reporting errors caused by `throw 'some string'`
// Unfortunately there is no way to figure out the stacktrace in this
// case, so if you ended up here trying to trace an error, look for
// `throw '<error message>'` somewhere in your codebase.
error = new SyntheticError(e);
}
try {
inExceptionHandler = true;
/* $FlowFixMe[class-object-subtyping] added when improving typing for this
* parameters */
// $FlowFixMe[incompatible-call]
reportException(error, isFatal, /*reportToConsole*/ true);
} finally {
inExceptionHandler = false;
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import typeof NativeExceptionsManager from '../NativeExceptionsManager';
export default ({
reportFatalException: jest.fn(),
reportSoftException: jest.fn(),
updateExceptionMessage: jest.fn(),
dismissRedbox: jest.fn(),
reportException: jest.fn(),
}: NativeExceptionsManager);
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,6 @@ function runExceptionsManagerTests() {
return {
default: {
reportException: jest.fn(),
// Used to show symbolicated messages, not part of this test.
updateExceptionMessage: () => {},
},
};
});
Expand Down
8 changes: 1 addition & 7 deletions packages/react-native/Libraries/Core/setUpErrorHandling.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,7 @@ ExceptionsManager.installConsoleErrorReporter();
if (!global.__fbDisableExceptionsManager) {
const handleError = (e: mixed, isFatal: boolean) => {
try {
// TODO(T196834299): We should really use a c++ turbomodule for this
if (
!global.RN$handleException ||
!global.RN$handleException(e, isFatal)
) {
ExceptionsManager.handleException(e, isFatal);
}
ExceptionsManager.handleException(e, isFatal);
} catch (ee) {
console.log('Failed to print error: ', ee.message);
throw e;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
NS_ASSUME_NONNULL_BEGIN

@protocol RCTExceptionsManagerDelegate <NSObject>

- (void)handleSoftJSExceptionWithMessage:(nullable NSString *)message
stack:(nullable NSArray *)stack
exceptionId:(NSNumber *)exceptionId
Expand All @@ -20,12 +19,6 @@ NS_ASSUME_NONNULL_BEGIN
stack:(nullable NSArray *)stack
exceptionId:(NSNumber *)exceptionId
extraDataAsJSON:(nullable NSString *)extraDataAsJSON;

@optional
- (void)updateJSExceptionWithMessage:(nullable NSString *)message
stack:(nullable NSArray *)stack
exceptionId:(NSNumber *)exceptionId;

@end

@interface RCTExceptionsManager : NSObject <RCTBridgeModule>
Expand Down
21 changes: 0 additions & 21 deletions packages/react-native/React/CoreModules/RCTExceptionsManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -99,27 +99,6 @@ - (void)reportFatal:(NSString *)message
[self reportFatal:message stack:stack exceptionId:exceptionId extraDataAsJSON:nil];
}

RCT_EXPORT_METHOD(updateExceptionMessage
: (NSString *)message stack
: (NSArray<NSDictionary *> *)stack exceptionId
: (double)exceptionId)
{
if (RCTRedBoxGetEnabled()) {
RCTRedBox *redbox = [_moduleRegistry moduleForName:"RedBox"];
[redbox updateErrorMessage:message withStack:stack errorCookie:(int)exceptionId];
}

if (_delegate && [_delegate respondsToSelector:@selector(updateJSExceptionWithMessage:stack:exceptionId:)]) {
[_delegate updateJSExceptionWithMessage:message stack:stack exceptionId:[NSNumber numberWithDouble:exceptionId]];
}
}

// Deprecated. Use reportFatalException directly instead.
RCT_EXPORT_METHOD(reportUnhandledException : (NSString *)message stack : (NSArray<NSDictionary *> *)stack)
{
[self reportFatalException:message stack:stack exceptionId:-1];
}

RCT_EXPORT_METHOD(dismissRedbox) {}

RCT_EXPORT_METHOD(reportException : (JS::NativeExceptionsManager::ExceptionData &)data)
Expand Down
4 changes: 0 additions & 4 deletions packages/react-native/ReactAndroid/api/ReactAndroid.api
Original file line number Diff line number Diff line change
Expand Up @@ -2212,7 +2212,6 @@ public abstract class com/facebook/react/devsupport/DevSupportManagerBase : com/
public fun startInspector ()V
public fun stopInspector ()V
public fun toggleElementInspector ()V
public fun updateJSError (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;I)V
}

public abstract interface class com/facebook/react/devsupport/DevSupportManagerBase$CallbackWithBundleLoader {
Expand Down Expand Up @@ -2380,7 +2379,6 @@ public class com/facebook/react/devsupport/ReleaseDevSupportManager : com/facebo
public fun startInspector ()V
public fun stopInspector ()V
public fun toggleElementInspector ()V
public fun updateJSError (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;I)V
}

public class com/facebook/react/devsupport/StackTraceHelper {
Expand Down Expand Up @@ -2516,7 +2514,6 @@ public abstract interface class com/facebook/react/devsupport/interfaces/DevSupp
public abstract fun startInspector ()V
public abstract fun stopInspector ()V
public abstract fun toggleElementInspector ()V
public abstract fun updateJSError (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;I)V
}

public abstract interface class com/facebook/react/devsupport/interfaces/DevSupportManager$PackagerLocationCustomizer {
Expand Down Expand Up @@ -3138,7 +3135,6 @@ public class com/facebook/react/modules/core/ExceptionsManagerModule : com/faceb
public fun reportException (Lcom/facebook/react/bridge/ReadableMap;)V
public fun reportFatalException (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;D)V
public fun reportSoftException (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;D)V
public fun updateExceptionMessage (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;D)V
}

public class com/facebook/react/modules/core/HeadlessJsTaskSupportModule : com/facebook/fbreact/specs/NativeHeadlessJsTaskSupportSpec {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,26 +279,6 @@ public Pair<String, StackFrame[]> processErrorCustomizers(Pair<String, StackFram
return errorInfo;
}

@Override
public void updateJSError(
final String message, final ReadableArray details, final int errorCookie) {
UiThreadUtil.runOnUiThread(
() -> {
// Since we only show the first JS error in a succession of JS errors, make sure we only
// update the error message for that error message. This assumes that updateJSError
// belongs to the most recent showNewJSError
if ((mRedBoxSurfaceDelegate != null && !mRedBoxSurfaceDelegate.isShowing())
|| errorCookie != mLastErrorCookie) {
return;
}

// The RedBox surface delegate will always show the latest error
updateLastErrorInfo(
message, StackTraceHelper.convertJsStackTrace(details), errorCookie, ErrorType.JS);
mRedBoxSurfaceDelegate.show();
});
}

@Override
public void hideRedboxDialog() {
if (mRedBoxSurfaceDelegate == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,6 @@ public open class ReleaseDevSupportManager : DevSupportManager {

override public fun destroyRootView(rootView: View?): Unit = Unit

override public fun updateJSError(
message: String?,
details: ReadableArray?,
errorCookie: Int
): Unit = Unit

override public fun hideRedboxDialog(): Unit = Unit

override public fun showDevOptionsDialog(): Unit = Unit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ public interface DevSupportManager : JSExceptionHandler {

public fun showNewJSError(message: String?, details: ReadableArray?, errorCookie: Int)

public fun updateJSError(message: String?, details: ReadableArray?, errorCookie: Int)

public fun hideRedboxDialog()

public fun showDevOptionsDialog()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,6 @@ public open class ExceptionsManagerModule(private val devSupportManager: DevSupp
}
}

override fun updateExceptionMessage(
title: String?,
details: ReadableArray?,
exceptionIdDouble: Double
) {
val exceptionId = exceptionIdDouble.toInt()
if (devSupportManager.devSupportEnabled) {
devSupportManager.updateJSError(title, details, exceptionId)
}
}

override fun dismissRedbox() {
if (devSupportManager.devSupportEnabled) {
devSupportManager.hideRedboxDialog()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ void objectAssign(
auto assign = Object.getPropertyAsFunction(runtime, "assign");
assign.callWithThis(runtime, Object, target, value);
}

jsi::Object wrapInErrorIfNecessary(
jsi::Runtime& runtime,
const jsi::Value& value) {
auto Error = runtime.global().getPropertyAsFunction(runtime, "Error");
auto isError =
value.isObject() && value.asObject(runtime).instanceOf(runtime, Error);
auto error = isError
? value.getObject(runtime)
: Error.callAsConstructor(runtime, value).getObject(runtime);
return error;
}
} // namespace

namespace facebook::react {
Expand Down Expand Up @@ -187,7 +199,7 @@ void JsErrorHandler::emitError(
jsi::JSError& error,
bool isFatal) {
auto message = error.getMessage();
auto errorObj = error.value().getObject(runtime);
auto errorObj = wrapInErrorIfNecessary(runtime, error.value());
auto componentStackValue = errorObj.getProperty(runtime, "componentStack");
if (!isLooselyNull(componentStackValue)) {
message += "\n" + stringifyToCpp(runtime, componentStackValue);
Expand Down
15 changes: 2 additions & 13 deletions packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,17 +391,6 @@ bool isTruthy(jsi::Runtime& runtime, const jsi::Value& value) {
return Boolean.call(runtime, value).getBool();
}

jsi::Value wrapInErrorIfNecessary(
jsi::Runtime& runtime,
const jsi::Value& value) {
auto Error = runtime.global().getPropertyAsFunction(runtime, "Error");
auto isError =
value.isObject() && value.asObject(runtime).instanceOf(runtime, Error);
auto error = isError ? value.getObject(runtime)
: Error.callAsConstructor(runtime, value);
return jsi::Value(runtime, error);
}

} // namespace

void ReactInstance::initializeRuntime(
Expand Down Expand Up @@ -448,8 +437,8 @@ void ReactInstance::initializeRuntime(
return jsi::Value(false);
}

auto jsError = jsi::JSError(
runtime, wrapInErrorIfNecessary(runtime, args[0]));
auto jsError =
jsi::JSError(runtime, jsi::Value(runtime, args[0]));
jsErrorHandler->handleError(runtime, jsError, isFatal);

return jsi::Value(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,6 @@ export interface Spec extends TurboModule {
exceptionId: number,
) => void;
+reportException?: (data: ExceptionData) => void;
+updateExceptionMessage: (
message: string,
stack: Array<StackFrame>,
exceptionId: number,
) => void;
// TODO(T53311281): This is a noop on iOS now. Implement it.
+dismissRedbox?: () => void;
}
Expand All @@ -74,13 +69,6 @@ const ExceptionsManager = {
) {
NativeModule.reportSoftException(message, stack, exceptionId);
},
updateExceptionMessage(
message: string,
stack: Array<StackFrame>,
exceptionId: number,
) {
NativeModule.updateExceptionMessage(message, stack, exceptionId);
},
dismissRedbox(): void {
if (Platform.OS !== 'ios' && NativeModule.dismissRedbox) {
// TODO(T53311281): This is a noop on iOS now. Implement it.
Expand Down