diff --git a/BUCK b/BUCK index 299c6347abd..24538162ef0 100644 --- a/BUCK +++ b/BUCK @@ -200,7 +200,6 @@ rn_xplat_cxx_library2( visibility = ["PUBLIC"], deps = [ "//xplat/folly:dynamic", - react_native_xplat_target("jserrorhandler:jserrorhandler"), ], ) diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index b8fd6f44608..047a7c2c4eb 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -1137,7 +1137,10 @@ struct RCTInstanceCallback : public InstanceCallback { // In state 3: do nothing. if (self->_valid && !self->_loading) { - [self showJsError:error onRedBox:self.redBox]; + if ([error userInfo][RCTJSRawStackTraceKey]) { + [self.redBox showErrorMessage:[error localizedDescription] withRawStack:[error userInfo][RCTJSRawStackTraceKey]]; + } + RCTFatal(error); // RN will stop, but let the rest of the app keep going. @@ -1168,20 +1171,15 @@ struct RCTInstanceCallback : public InstanceCallback { [[NSNotificationCenter defaultCenter] postNotificationName:RCTJavaScriptDidFailToLoadNotification object:self->_parentBridge userInfo:@{@"bridge" : self, @"error" : error}]; - [self showJsError:error onRedBox:redBox]; + + if ([error userInfo][RCTJSRawStackTraceKey]) { + [redBox showErrorMessage:[error localizedDescription] withRawStack:[error userInfo][RCTJSRawStackTraceKey]]; + } + RCTFatal(error); }); } -- (void)showJsError:(NSError *)error onRedBox:(RCTRedBox *)redbox -{ - if ([error userInfo][RCTJSStackTraceKey]) { - [redbox showErrorMessage:[error localizedDescription] withStack:[error userInfo][RCTJSStackTraceKey]]; - } else if ([error userInfo][RCTJSRawStackTraceKey]) { - [redbox showErrorMessage:[error localizedDescription] withRawStack:[error userInfo][RCTJSRawStackTraceKey]]; - } -} - RCT_NOT_IMPLEMENTED(-(instancetype)initWithDelegate : (__unused id)delegate bundleURL : (__unused NSURL *)bundleURL moduleProvider diff --git a/React/CxxModule/RCTCxxUtils.mm b/React/CxxModule/RCTCxxUtils.mm index 6be964fabdf..03f0ad0c83d 100644 --- a/React/CxxModule/RCTCxxUtils.mm +++ b/React/CxxModule/RCTCxxUtils.mm @@ -7,9 +7,6 @@ #import "RCTCxxUtils.h" -#include - -#import #import #import #import @@ -23,6 +20,8 @@ namespace facebook { namespace react { +using facebook::jsi::JSError; + std::vector> createNativeModules(NSArray *modules, RCTBridge *bridge, const std::shared_ptr &instance) { @@ -43,34 +42,13 @@ createNativeModules(NSArray *modules, RCTBridge *bridge, const static NSError *errorWithException(const std::exception &e) { - NSString *msg; + NSString *msg = @(e.what()); NSMutableDictionary *errorInfo = [NSMutableDictionary dictionary]; - const auto *jsError = dynamic_cast(&e); - if (jsError && RCTGetParseUnhandledJSErrorStackNatively()) { - MapBuffer errorMap = JsErrorHandler::parseErrorStack(*jsError, true, false); - - NSString *message = [NSString stringWithCString:errorMap.getString(JSErrorHandlerKey::kErrorMessage).c_str() - encoding:[NSString defaultCStringEncoding]]; - auto frames = errorMap.getMapBufferList(JSErrorHandlerKey::kAllStackFrames); - NSMutableArray *stack = [[NSMutableArray alloc] init]; - for (auto const &mapBuffer : frames) { - NSDictionary *frame = @{ - @"file" : [NSString stringWithCString:mapBuffer.getString(JSErrorHandlerKey::kFrameFileName).c_str() - encoding:[NSString defaultCStringEncoding]], - @"methodName" : [NSString stringWithCString:mapBuffer.getString(JSErrorHandlerKey::kFrameMethodName).c_str() - encoding:[NSString defaultCStringEncoding]], - @"lineNumber" : [NSNumber numberWithInt:mapBuffer.getInt(JSErrorHandlerKey::kFrameLineNumber)], - @"column" : [NSNumber numberWithInt:mapBuffer.getInt(JSErrorHandlerKey::kFrameColumnNumber)], - }; - [stack addObject:frame]; - } - - msg = [@"Unhandled JS Exception: " stringByAppendingString:message]; - errorInfo[RCTJSStackTraceKey] = stack; - errorInfo[RCTJSRawStackTraceKey] = @(e.what()); - } else { - msg = @(e.what()); + const auto *jsError = dynamic_cast(&e); + if (jsError) { + errorInfo[RCTJSRawStackTraceKey] = @(jsError->getStack().c_str()); + msg = [@"Unhandled JS Exception: " stringByAppendingString:msg]; } NSError *nestedError; diff --git a/ReactCommon/React-Fabric.podspec b/ReactCommon/React-Fabric.podspec index b9a13624a51..c28eee60d06 100644 --- a/ReactCommon/React-Fabric.podspec +++ b/ReactCommon/React-Fabric.podspec @@ -254,6 +254,8 @@ Pod::Spec.new do |s| end s.subspec "mapbuffer" do |ss| + ss.dependency folly_dep_name, folly_version + ss.compiler_flags = folly_compiler_flags ss.source_files = "react/renderer/mapbuffer/**/*.{m,mm,cpp,h}" ss.exclude_files = "react/renderer/mapbuffer/tests" ss.header_dir = "react/renderer/mapbuffer" diff --git a/ReactCommon/jserrorhandler/BUCK b/ReactCommon/jserrorhandler/BUCK index e0515033095..e7ef279bb10 100644 --- a/ReactCommon/jserrorhandler/BUCK +++ b/ReactCommon/jserrorhandler/BUCK @@ -23,6 +23,8 @@ rn_xplat_cxx_library( "PUBLIC", ], deps = [ + "//xplat/folly:dynamic", + "//xplat/folly:json", "//xplat/jsi:jsi", react_native_xplat_target("react/renderer/mapbuffer:mapbuffer"), ], diff --git a/ReactCommon/jserrorhandler/JsErrorHandler.cpp b/ReactCommon/jserrorhandler/JsErrorHandler.cpp index be74dc5da2b..0902e68b2b1 100644 --- a/ReactCommon/jserrorhandler/JsErrorHandler.cpp +++ b/ReactCommon/jserrorhandler/JsErrorHandler.cpp @@ -17,10 +17,8 @@ namespace react { using facebook::react::JSErrorHandlerKey; -MapBuffer JsErrorHandler::parseErrorStack( - const jsi::JSError &error, - bool isFatal, - bool isHermes) { +static MapBuffer +parseErrorStack(const jsi::JSError &error, bool isFatal, bool isHermes) { /** * This parses the different stack traces and puts them into one format * This borrows heavily from TraceKit (https://github.com/occ/TraceKit) @@ -101,7 +99,7 @@ JsErrorHandler::~JsErrorHandler() {} void JsErrorHandler::handleJsError(const jsi::JSError &error, bool isFatal) { // TODO: Current error parsing works and is stable. Can investigate using // REGEX_HERMES to get additional Hermes data, though it requires JS setup. - MapBuffer errorMap = JsErrorHandler::parseErrorStack(error, isFatal, false); + MapBuffer errorMap = parseErrorStack(error, isFatal, false); _jsErrorHandlingFunc(std::move(errorMap)); } diff --git a/ReactCommon/jserrorhandler/JsErrorHandler.h b/ReactCommon/jserrorhandler/JsErrorHandler.h index ca5af45425b..90383e17ca7 100644 --- a/ReactCommon/jserrorhandler/JsErrorHandler.h +++ b/ReactCommon/jserrorhandler/JsErrorHandler.h @@ -26,9 +26,6 @@ class JsErrorHandler { public: using JsErrorHandlingFunc = std::function; - static MapBuffer - parseErrorStack(const jsi::JSError &error, bool isFatal, bool isHermes); - JsErrorHandler(JsErrorHandlingFunc jsErrorHandlingFunc); ~JsErrorHandler(); diff --git a/ReactCommon/jserrorhandler/React-jserrorhandler.podspec b/ReactCommon/jserrorhandler/React-jserrorhandler.podspec deleted file mode 100644 index cfb7594ee2a..00000000000 --- a/ReactCommon/jserrorhandler/React-jserrorhandler.podspec +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright (c) Meta Platforms, Inc. and affiliates. -# -# This source code is licensed under the MIT license found in the -# LICENSE file in the root directory of this source tree. - -require "json" - -package = JSON.parse(File.read(File.join(__dir__, "..", "..", "package.json"))) -version = package['version'] - -source = { :git => 'https://github.com/facebook/react-native.git' } -if version == '1000.0.0' - # This is an unpublished version, use the latest commit hash of the react-native repo, which we’re presumably in. - source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1") -else - source[:tag] = "v#{version}" -end - -Pod::Spec.new do |s| - s.name = "React-jserrorhandler" - s.version = version - s.summary = "-" # TODO - s.homepage = "https://reactnative.dev/" - s.license = package["license"] - s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "12.4", :tvos => "12.4" } - s.public_header_files = [ "JsErrorHandler.h" ] - s.source = source - s.source_files = "*.{cpp,h}" - s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "" } - s.header_dir = "jserrorhandler" - - s.dependency "React-jsi", version - s.dependency "React-Fabric/mapbuffer", version - -end diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock index 336f7d51707..fedd81b021d 100644 --- a/packages/rn-tester/Podfile.lock +++ b/packages/rn-tester/Podfile.lock @@ -620,9 +620,6 @@ PODS: - React-jsiexecutor (= 1000.0.0) - React-jsinspector (= 1000.0.0) - React-perflogger (= 1000.0.0) - - React-jserrorhandler (1000.0.0): - - React-Fabric/mapbuffer (= 1000.0.0) - - React-jsi (= 1000.0.0) - React-jsi (1000.0.0): - hermes-engine - React-jsidynamic (1000.0.0): @@ -799,7 +796,6 @@ DEPENDENCIES: - React-Fabric (from `../../ReactCommon`) - React-graphics (from `../../ReactCommon/react/renderer/graphics`) - React-hermes (from `../../ReactCommon/hermes`) - - React-jserrorhandler (from `../../ReactCommon/jserrorhandler`) - React-jsi (from `../../ReactCommon/jsi`) - React-jsidynamic (from `../../ReactCommon/jsi`) - React-jsiexecutor (from `../../ReactCommon/jsiexecutor`) @@ -883,8 +879,6 @@ EXTERNAL SOURCES: :path: "../../ReactCommon/react/renderer/graphics" React-hermes: :path: "../../ReactCommon/hermes" - React-jserrorhandler: - :path: "../../ReactCommon/jserrorhandler" React-jsi: :path: "../../ReactCommon/jsi" React-jsidynamic: @@ -964,10 +958,9 @@ SPEC CHECKSUMS: React-Core: 3965263aa4b4e1ebf7b4fdb50d2f49ce7bf28f63 React-CoreModules: 675170bccf156da3a3348e04e2036ce401b2010d React-cxxreact: 7276467c246302fedf598cc40d7003896ddb20ba - React-Fabric: e177589b59ae3ae3dd3340190adcde9cf01ebceb + React-Fabric: 141459e61c825acf02d26ece099acbd9cbd87b99 React-graphics: 5ccc9cc0d91794fd42bc1c693e9aea207554bbef React-hermes: 0a5145bae4207edf0def8e28fbcb6a8fd6e806c2 - React-jserrorhandler: f0e756378ad46f5f3448f097a736eb5249de262b React-jsi: c24dbcfdf7ea075138b73372387c7f17c0db56ef React-jsidynamic: 2b14ac1b6d3a1b7daa1e5a424b98de87da981698 React-jsiexecutor: 14e899380e3fe9ca74c4e19727540a03e7574721 diff --git a/scripts/react_native_pods.rb b/scripts/react_native_pods.rb index 326cb50ee4f..73b44c12bab 100644 --- a/scripts/react_native_pods.rb +++ b/scripts/react_native_pods.rb @@ -101,10 +101,10 @@ def use_react_native! ( else setup_jsc!(:react_native_path => prefix, :fabric_enabled => fabric_enabled) end - pod 'React-jserrorhandler', :path => "#{prefix}/ReactCommon/jserrorhandler" pod 'React-jsidynamic', :path => "#{prefix}/ReactCommon/jsi" pod 'React-jsiexecutor', :path => "#{prefix}/ReactCommon/jsiexecutor" pod 'React-jsinspector', :path => "#{prefix}/ReactCommon/jsinspector" + pod 'React-callinvoker', :path => "#{prefix}/ReactCommon/callinvoker" pod 'React-runtimeexecutor', :path => "#{prefix}/ReactCommon/runtimeexecutor" pod 'React-perflogger', :path => "#{prefix}/ReactCommon/reactperflogger"