Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

earlyjs: Integrate c++ pipeline with all ios apps #47168

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
12 changes: 0 additions & 12 deletions packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -178,18 +178,6 @@ - (void)hostDidStart:(RCTHost *)host
{
}

- (void)host:(RCTHost *)host
didReceiveJSErrorStack:(NSArray<NSDictionary<NSString *, id> *> *)stack
message:(NSString *)message
originalMessage:(NSString *_Nullable)originalMessage
name:(NSString *_Nullable)name
componentStack:(NSString *_Nullable)componentStack
exceptionId:(NSUInteger)exceptionId
isFatal:(BOOL)isFatal
extraData:(NSDictionary<NSString *, id> *)extraData
{
}

#pragma mark - Bridge and Bridge Adapter properties

- (RCTBridge *)bridge
Expand Down
42 changes: 24 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,30 @@ 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
11 changes: 0 additions & 11 deletions packages/react-native/React/CoreModules/RCTExceptionsManager.h
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 All @@ -38,10 +31,6 @@ NS_ASSUME_NONNULL_BEGIN
- (void)reportFatalException:(nullable NSString *)message
stack:(nullable NSArray<NSDictionary *> *)stack
exceptionId:(double)exceptionId;
- (void)reportJsException:(nullable NSString *)message
stack:(nullable NSArray<NSDictionary *> *)stack
exceptionId:(double)exceptionId
isFatal:(bool)isFatal;

@property (nonatomic, weak) id<RCTExceptionsManagerDelegate> delegate;

Expand Down
33 changes: 0 additions & 33 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 Expand Up @@ -157,18 +136,6 @@ - (void)reportFatal:(NSString *)message
}
}

- (void)reportJsException:(nullable NSString *)message
stack:(nullable NSArray<NSDictionary *> *)stack
exceptionId:(double)exceptionId
isFatal:(bool)isFatal
{
if (isFatal) {
[self reportFatalException:message stack:stack exceptionId:exceptionId];
} else {
[self reportSoftException:message stack:stack exceptionId:exceptionId];
}
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
(const facebook::react::ObjCTurboModule::InitParams &)params
{
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 @@ -115,51 +115,6 @@ - (void)testCallFunctionOnJSModule
XCTAssertEqualObjects(shimmedRCTInstance.args, args);
}

- (void)testDidReceiveErrorStack
{
id<RCTInstanceDelegate> instanceDelegate = (id<RCTInstanceDelegate>)_subject;

NSMutableArray<NSDictionary<NSString *, id> *> *stack = [NSMutableArray array];

NSMutableDictionary<NSString *, id> *stackFrame0 = [NSMutableDictionary dictionary];
stackFrame0[@"linenumber"] = @(3);
stackFrame0[@"column"] = @(4);
stackFrame0[@"methodname"] = @"method1";
stackFrame0[@"file"] = @"file1.js";
[stack addObject:stackFrame0];

NSMutableDictionary<NSString *, id> *stackFrame1 = [NSMutableDictionary dictionary];
stackFrame0[@"linenumber"] = @(63);
stackFrame0[@"column"] = @(44);
stackFrame0[@"methodname"] = @"method2";
stackFrame0[@"file"] = @"file2.js";
[stack addObject:stackFrame1];

id extraData = [NSDictionary dictionary];

[instanceDelegate instance:[OCMArg any]
didReceiveJSErrorStack:stack
message:@"message"
originalMessage:nil
name:nil
componentStack:nil
exceptionId:5
isFatal:YES
extraData:extraData];

OCMVerify(
OCMTimes(1),
[_mockHostDelegate host:_subject
didReceiveJSErrorStack:stack
message:@"message"
originalMessage:nil
name:nil
componentStack:nil
exceptionId:5
isFatal:YES
extraData:extraData]);
}

- (void)testDidInitializeRuntime
{
id<RCTHostRuntimeDelegate> mockRuntimeDelegate = OCMProtocolMock(@protocol(RCTHostRuntimeDelegate));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ folly_version = folly_config[:version]
folly_dep_name = folly_config[:dep_name]

boost_config = get_boost_config()
boost_compiler_flags = boost_config[:compiler_flags]
boost_compiler_flags = boost_config[:compiler_flags]

header_search_paths = [
"$(PODS_ROOT)/boost",
Expand Down Expand Up @@ -70,6 +70,8 @@ Pod::Spec.new do |s|
s.dependency "React-jserrorhandler"
s.dependency "React-jsinspector"

add_dependency(s, "ReactCodegen")

if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1"
s.dependency "hermes-engine"
s.dependency "React-RuntimeHermes"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,6 @@ typedef NSURL *_Nullable (^RCTHostBundleURLProvider)(void);

@protocol RCTHostDelegate <NSObject>

- (void)host:(RCTHost *)host
didReceiveJSErrorStack:(NSArray<NSDictionary<NSString *, id> *> *)stack
message:(NSString *)message
originalMessage:(NSString *_Nullable)originalMessage
name:(NSString *_Nullable)name
componentStack:(NSString *_Nullable)componentStack
exceptionId:(NSUInteger)exceptionId
isFatal:(BOOL)isFatal
extraData:(NSDictionary<NSString *, id> *)extraData;

- (void)hostDidStart:(RCTHost *)host;

@optional
Expand Down
Loading
Loading