【问题标题】:how to catch uncaught exception (globally) in react native如何在本机反应中捕获未捕获的异常(全局)
【发布时间】:2015-06-18 14:35:05
【问题描述】:

有谁知道捕获所有未捕获异常(全局)的最佳方法是什么,以便我可以将崩溃报告发送回服务器?我似乎无法在 react native docs 或 github 上找到任何信息。

【问题讨论】:

  • 你到底为什么要这么做?

标签: react-native


【解决方案1】:

您可能会覆盖 React Native 用于开发的异常日志记录:

ErrorUtils.setGlobalHandler(function() {
// your handler here
});

https://github.com/facebook/react-native/blob/522fd33d6f3c8fb339b0dde35b05df34c1233306/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js#L46

然后,您可能需要编写一些向 JS 公开的 Obj-C,具体取决于您的具体要求。

【讨论】:

  • 谢谢,我想这正是我要找的!
【解决方案2】:

这就是我的做法:

第 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
}

就是这样!

【讨论】:

  • 请问 parseErrorStack 函数应该做什么?当我尝试在 chrome 上记录错误参数时,我得到了一些输出,但在 react-native 上我只得到一个空对象
  • 嘿,ospfranco,我刚刚添加了完整的代码,抱歉耽搁了。
  • @SudoPlz 你能解释一下我应该在哪里使用这个代码吗?
  • @Ansal Ali 你可以在代码的任何地方使用它,它应该可以工作。理想情况下,我会在应用程序的初始化文件中使用它。 (在第一个组件加载之前)。
  • @Ansal Ali 看看这个文件:github.com/SudoPlz/react-native-bugsnag/blob/master/lib/… 它可能会帮助您了解您正在做的不同的事情。我使用该代码很长时间了,它运行良好。
【解决方案3】:

你可以试试https://github.com/master-atul/react-native-exception-handler。

一个 react 原生模块,允许您注册一个全局错误处理程序,该处理程序可以捕获致命/非致命未捕获异常。该模块有助于防止 RN 应用程序在没有向用户发出优雅消息的情况下突然崩溃。

【讨论】:

    【解决方案4】:

    有一种原生方式。

    RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_scriptURL
                                          moduleProvider:^{
                                            id<RCTExceptionsManagerDelegate> customDelegate = ...
                                            return @[[RCTExceptionsManager initWithDelegate:customDelegate];
                                          }
                                           launchOptions:nil];
    

    只需将您的报告逻辑放入customDelegate。

    【讨论】:

    • 如果您有适用于 Android 的相应解决方案,这对我很有帮助。
    • @jeevium 你可以在Android中使用Thread.setDefaultUncaughtExceptionHandler
    【解决方案5】:

    现在有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 中间件。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-16
    • 2018-06-14
    • 2014-07-03
    • 1970-01-01
    • 2010-09-28
    • 2016-03-19
    相关资源
    最近更新 更多