Skip to content

Commit

Permalink
[skip ci] earlyjs: Integrate c++ pipeline with all ios apps
Browse files Browse the repository at this point in the history
Summary:
Now, all ios apps will just be integrated with the c++ error reporting pipeline, with zero configuration.

Changelog: [Internal]

Reviewed By: philIip

Differential Revision: D64615457
  • Loading branch information
RSNara authored and facebook-github-bot committed Oct 25, 2024
1 parent f457523 commit 6ab2c9e
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 52 deletions.
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
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)reportJsException:(nullable NSString *)message
stack:(nullable NSArray<NSDictionary *> *)stack
exceptionId:(double)exceptionId
isFatal:(bool)isFatal;
isFatal:(bool)isFatal __attribute__((deprecated));

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

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,6 +27,15 @@ typedef NSURL *_Nullable (^RCTHostBundleURLProvider)(void);

@protocol RCTHostDelegate <NSObject>

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

@optional
- (void)loadBundleAtURL:(NSURL *)sourceURL
onProgress:(RCTSourceLoadProgressBlock)onProgress
onComplete:(RCTSourceLoadBlock)loadCallback;

// TODO(T205780509): Remove this api in react native v0.78
// The bridgeless js error handling api will just call into exceptionsmanager directly
- (void)host:(RCTHost *)host
didReceiveJSErrorStack:(NSArray<NSDictionary<NSString *, id> *> *)stack
message:(NSString *)message
Expand All @@ -35,15 +44,7 @@ typedef NSURL *_Nullable (^RCTHostBundleURLProvider)(void);
componentStack:(NSString *_Nullable)componentStack
exceptionId:(NSUInteger)exceptionId
isFatal:(BOOL)isFatal
extraData:(NSDictionary<NSString *, id> *)extraData;

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

@optional
- (void)loadBundleAtURL:(NSURL *)sourceURL
onProgress:(RCTSourceLoadProgressBlock)onProgress
onComplete:(RCTSourceLoadBlock)loadCallback;

extraData:(NSDictionary<NSString *, id> *)extraData __attribute__((deprecated));
@end

@protocol RCTHostRuntimeDelegate <NSObject>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ - (void)dealloc

#pragma mark - RCTInstanceDelegate

- (void)instance:(RCTInstance *)instance
- (BOOL)instance:(RCTInstance *)instance
didReceiveJSErrorStack:(NSArray<NSDictionary<NSString *, id> *> *)stack
message:(NSString *)message
originalMessage:(NSString *_Nullable)originalMessage
Expand All @@ -325,6 +325,12 @@ - (void)instance:(RCTInstance *)instance
isFatal:(BOOL)isFatal
extraData:(NSDictionary<NSString *, id> *)extraData
{
if (![_hostDelegate respondsToSelector:@selector(host:
didReceiveJSErrorStack:message:originalMessage:name:componentStack
:exceptionId:isFatal:extraData:)]) {
return NO;
}

[_hostDelegate host:self
didReceiveJSErrorStack:stack
message:message
Expand All @@ -334,6 +340,7 @@ - (void)instance:(RCTInstance *)instance
exceptionId:exceptionId
isFatal:isFatal
extraData:extraData];
return YES;
}

- (void)instance:(RCTInstance *)instance didInitializeRuntime:(facebook::jsi::Runtime &)runtime
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,23 @@ RCT_EXTERN void RCTInstanceSetRuntimeDiagnosticFlags(NSString *_Nullable flags);

@protocol RCTInstanceDelegate <RCTContextContainerHandling>

- (void)instance:(RCTInstance *)instance
- (void)instance:(RCTInstance *)instance didInitializeRuntime:(facebook::jsi::Runtime &)runtime;

- (void)loadBundleAtURL:(NSURL *)sourceURL
onProgress:(RCTSourceLoadProgressBlock)onProgress
onComplete:(RCTSourceLoadBlock)loadCallback;

// TODO(T205780509): Remove this api in react native v0.78
// The bridgeless js error handling api will just call into exceptionsmanager directly
- (BOOL)instance:(RCTInstance *)instance
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)instance:(RCTInstance *)instance didInitializeRuntime:(facebook::jsi::Runtime &)runtime;

- (void)loadBundleAtURL:(NSURL *)sourceURL
onProgress:(RCTSourceLoadProgressBlock)onProgress
onComplete:(RCTSourceLoadBlock)loadCallback;

extraData:(NSDictionary<NSString *, id> *)extraData __attribute__((deprecated));
@end

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#import <memory>

#import <FBReactNativeSpec/FBReactNativeSpec.h>
#import <React/NSDataBigString.h>
#import <React/RCTAssert.h>
#import <React/RCTBridge+Inspector.h>
Expand Down Expand Up @@ -467,32 +468,57 @@ - (void)_loadScriptFromSource:(RCTSource *)source

- (void)_handleJSError:(const JsErrorHandler::ParsedError &)error withRuntime:(jsi::Runtime &)runtime
{
NSString *message = @(error.message.c_str());
NSMutableDictionary<NSString *, id> *errorData = [NSMutableDictionary new];
errorData[@"message"] = @(error.message.c_str());
if (error.originalMessage) {
errorData[@"originalMessage"] = @(error.originalMessage->c_str());
}
if (error.name) {
errorData[@"name"] = @(error.name->c_str());
}
if (error.componentStack) {
errorData[@"componentStack"] = @(error.componentStack->c_str());
}

NSMutableArray<NSDictionary<NSString *, id> *> *stack = [NSMutableArray new];
for (const JsErrorHandler::ParsedError::StackFrame &frame : error.stack) {
[stack addObject:@{
@"file" : frame.file ? @((*frame.file).c_str()) : [NSNull null],
@"methodName" : @(frame.methodName.c_str()),
@"lineNumber" : frame.lineNumber ? @(*frame.lineNumber) : [NSNull null],
@"column" : frame.column ? @(*frame.column) : [NSNull null],
}];
NSMutableDictionary<NSString *, id> *stackFrame = [NSMutableDictionary new];
if (frame.file) {
stackFrame[@"file"] = @(frame.file->c_str());
}
stackFrame[@"methodName"] = @(frame.methodName.c_str());
if (frame.lineNumber) {
stackFrame[@"lineNumber"] = @(*frame.lineNumber);
}
if (frame.column) {
stackFrame[@"column"] = @(*frame.column);
}
[stack addObject:stackFrame];
}

NSString *originalMessage = error.originalMessage ? @(error.originalMessage->c_str()) : nil;
NSString *name = error.name ? @(error.name->c_str()) : nil;
NSString *componentStack = error.componentStack ? @(error.componentStack->c_str()) : nil;
errorData[@"stack"] = stack;
errorData[@"id"] = @(error.id);
errorData[@"isFatal"] = @(error.isFatal);

id extraData =
TurboModuleConvertUtils::convertJSIValueToObjCObject(runtime, jsi::Value(runtime, error.extraData), nullptr);
if (extraData) {
errorData[@"extraData"] = extraData;
}

[_delegate instance:self
didReceiveJSErrorStack:stack
message:message
originalMessage:originalMessage
name:name
componentStack:componentStack
exceptionId:error.id
isFatal:error.isFatal
extraData:extraData];
if (![_delegate instance:self
didReceiveJSErrorStack:errorData[@"stack"]
message:errorData[@"message"]
originalMessage:errorData[@"originalMessage"]
name:errorData[@"name"]
componentStack:errorData[@"componentStack"]
exceptionId:error.id
isFatal:errorData[@"isFatal"]
extraData:errorData[@"extraData"]]) {
JS::NativeExceptionsManager::ExceptionData jsErrorData{errorData};
id<NativeExceptionsManagerSpec> exceptionsManager = [_turboModuleManager moduleForName:"ExceptionsManager"];
[exceptionsManager reportException:jsErrorData];
}
}

@end

0 comments on commit 6ab2c9e

Please sign in to comment.