Revert D40387938: 4/n Display a RedBox with the JS stack (instead of native stack) when an unhandled JS exceptions occurs

Differential Revision:
D40387938 (ff398e4e26)

Original commit changeset: 2abea657476d

Original Phabricator Diff: D40387938 (ff398e4e26)

fbshipit-source-id: 0b5dbe417abf25d5723c70337189dfb42570e56d
This commit is contained in:
Donald Webster 2022-10-21 12:59:54 -07:00 коммит произвёл Facebook GitHub Bot
Родитель 48db6be269
Коммит 9e68eea2c8
10 изменённых файлов: 25 добавлений и 94 удалений

1
BUCK
Просмотреть файл

@ -200,7 +200,6 @@ rn_xplat_cxx_library2(
visibility = ["PUBLIC"],
deps = [
"//xplat/folly:dynamic",
react_native_xplat_target("jserrorhandler:jserrorhandler"),
],
)

Просмотреть файл

@ -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<RCTBridgeDelegate>)delegate bundleURL
: (__unused NSURL *)bundleURL moduleProvider

Просмотреть файл

@ -7,9 +7,6 @@
#import "RCTCxxUtils.h"
#include <JsErrorHandler/JsErrorHandler.h>
#import <React/RCTConstants.h>
#import <React/RCTFollyConvert.h>
#import <React/RCTModuleData.h>
#import <React/RCTUtils.h>
@ -23,6 +20,8 @@
namespace facebook {
namespace react {
using facebook::jsi::JSError;
std::vector<std::unique_ptr<NativeModule>>
createNativeModules(NSArray<RCTModuleData *> *modules, RCTBridge *bridge, const std::shared_ptr<Instance> &instance)
{
@ -43,34 +42,13 @@ createNativeModules(NSArray<RCTModuleData *> *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<const jsi::JSError *>(&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<const JSError *>(&e);
if (jsError) {
errorInfo[RCTJSRawStackTraceKey] = @(jsError->getStack().c_str());
msg = [@"Unhandled JS Exception: " stringByAppendingString:msg];
}
NSError *nestedError;

Просмотреть файл

@ -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"

Просмотреть файл

@ -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"),
],

Просмотреть файл

@ -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));
}

Просмотреть файл

@ -26,9 +26,6 @@ class JsErrorHandler {
public:
using JsErrorHandlingFunc = std::function<void(MapBuffer errorMap)>;
static MapBuffer
parseErrorStack(const jsi::JSError &error, bool isFatal, bool isHermes);
JsErrorHandler(JsErrorHandlingFunc jsErrorHandlingFunc);
~JsErrorHandler();

Просмотреть файл

@ -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 were 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

Просмотреть файл

@ -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

Просмотреть файл

@ -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"