【发布时间】:2015-06-18 14:35:05
【问题描述】:
有谁知道捕获所有未捕获异常(全局)的最佳方法是什么,以便我可以将崩溃报告发送回服务器?我似乎无法在 react native docs 或 github 上找到任何信息。
【问题讨论】:
-
你到底为什么要这么做?
标签: react-native
有谁知道捕获所有未捕获异常(全局)的最佳方法是什么,以便我可以将崩溃报告发送回服务器?我似乎无法在 react native docs 或 github 上找到任何信息。
【问题讨论】:
标签: react-native
您可能会覆盖 React Native 用于开发的异常日志记录:
ErrorUtils.setGlobalHandler(function() {
// your handler here
});
然后,您可能需要编写一些向 JS 公开的 Obj-C,具体取决于您的具体要求。
【讨论】:
这就是我的做法:
第 1 步:我们像这样拦截 react-native 错误处理程序:
//intercept react-native error handling
if (ErrorUtils._globalHandler) {
this.defaultHandler = ErrorUtils.getGlobalHandler && ErrorUtils.getGlobalHandler() || ErrorUtils._globalHandler;
ErrorUtils.setGlobalHandler(this.wrapGlobalHandler); //feed errors directly to our wrapGlobalHandler function
}
第 2 步: 现在我们的wrapGlobalHandler 会在出现未处理错误时被调用。所以对这个函数中的错误做任何你想做的事情。
然后对错误进行处理:
async function wrapGlobalHandler(error, isFatal){
const stack = parseErrorStack(error);
//do anything with the error here
this.defaultHandler(error, isFatal); //after you're finished, call the defaultHandler so that react-native also gets the error
}
完整代码在这里:
import stacktraceParser from 'stacktrace-parser';
const parseErrorStack = (error) => {
if (!error || !error.stack) {
return [];
}
return Array.isArray(error.stack) ? error.stack :
stacktraceParser.parse(error.stack);
};
// intercept react-native error handling
if (ErrorUtils._globalHandler) {
this.defaultHandler = (ErrorUtils.getGlobalHandler
&& ErrorUtils.getGlobalHandler())
|| ErrorUtils._globalHandler;
ErrorUtils.setGlobalHandler(this.wrapGlobalHandler); // feed errors directly to our wrapGlobalHandler function
}
async function wrapGlobalHandler(error, isFatal) {
const stack = parseErrorStack(error);
//do anything with the error here
this.defaultHandler(error, isFatal); //after you're finished, call the defaultHandler so that react-native also gets the error
}
就是这样!
【讨论】:
你可以试试https://github.com/master-atul/react-native-exception-handler。
一个 react 原生模块,允许您注册一个全局错误处理程序,该处理程序可以捕获致命/非致命未捕获异常。该模块有助于防止 RN 应用程序在没有向用户发出优雅消息的情况下突然崩溃。
【讨论】:
有一种原生方式。
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_scriptURL
moduleProvider:^{
id<RCTExceptionsManagerDelegate> customDelegate = ...
return @[[RCTExceptionsManager initWithDelegate:customDelegate];
}
launchOptions:nil];
只需将您的报告逻辑放入customDelegate。
【讨论】:
Thread.setDefaultUncaughtExceptionHandler
现在有react-native-error-reporter,它以一种非常简单的方式几乎可以解决问题:
npm i react-native-error-reporter --save
rnpm link
然后将此行添加到您的代码中:
import ErrorReporter from 'react-native-error-reporter';
ErrorReporter.init("vanson@vanportdev.com", "My App's Crash Report");
如果你使用 Redux,你可能想试试redux-catch 中间件。
【讨论】:
react-native-error-reporter 更好,现在react-native-exception-handler 为您提供了一个用户界面和一种捕获本机错误的方法。 github.com/master-atul/react-native-exception-handler