如何在React Native中全局处理错误?

问题描述 投票:0回答:2

我不太清楚在反应本机应用程序中能够全局处理错误的过程。如何捕获任何应用程序错误并据此做出响应?例如,显示错误屏幕和“回家”按钮,或者运行特定代码(例如重试请求),以便用户可以从此类错误中恢复。 使用哪些方法来处理react-native中的全局错误?

reactjs react-native error-handling
2个回答
20
投票

错误边界 API 仅适用于类组件,如果您将这些生命周期方法之一定义为 static

getDerivedStateFromError()
componentDidCatch()
,则类组件将成为错误边界。

React-error-boundary 是一个基于 React 错误边界 API 的简单可重用组件,它为组件提供了包装器,并自动捕获子组件层次结构中的所有错误,并且还提供了恢复组件树的好方法。

我的建议是使用react-error-boundary组件包装应用程序中的每个导航屏幕,并提供一个后备组件以确保用户知道发生了什么,也许您可以通过重新渲染来恢复屏幕。

最好的方法是创建一个 Errorhandler 组件,如下所示。

import * as React from "react";
import { ErrorBoundary } from "react-error-boundary";
import { View, StyleSheet, Button } from "react-native";
import { Text } from "components";
const myErrorHandler = (error: Error) => {
  // Do something with the error
  // E.g. reporting errorr using sentry ( see part 3)
};
function ErrorFallback({ resetErrorBoundary }) {
  return (
    <View style={[styles.container]}>
      <View>
        <Text> Something went wrong: </Text>
        <Button title="try Again" onPress={resetErrorBoundary} />
      </View>
    </View>
  );
}
export const ErrorHandler = ({ children }: { children: React.ReactNode }) => (
  <ErrorBoundary FallbackComponent={ErrorFallback} onError={myErrorHandler}>
    {children}
  </ErrorBoundary>
);
const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: "column",
    alignItems: "stretch",
    justifyContent: "center",
    alignContent: "center",
    paddingHorizontal: 12,
  },
});

如您所见,我使用错误后备组件向用户提供更多信息,而不是白屏。

我还添加了一个重试按钮,以编程方式重新渲染屏幕,作为恢复屏幕并解决问题的方法。当用户单击重试按钮时,错误边界将触发屏幕组件的重新渲染,这有助于避免错误并显示正确的组件。

了解更多关于错误恢复

值得一提的是,我还为每个可能引发错误的组件包装了错误边界组件。

错误边界足以应对 JS 异常吗? 不幸的是,事实并非如此,错误边界不会捕获以下错误:

  • 事件处理程序
  • 异步代码(例如 setTimeout 或 requestAnimationFrame 回调)
  • 错误边界本身(而不是其子级)抛出的错误

(来源:文档

这些限制导致我们使用 react-native-exception-handler 为应用程序创建一个全局处理程序,可以捕获所有未捕获的 Js 错误。

react-native-exception-handler 是一个 React Native 模块,可让您注册一个全局错误处理程序来捕获致命/非致命的未捕获异常。

要使其工作,您需要安装并链接模块,然后注册 Js 异常的全局处理程序,如下所示:

import { setJSExceptionHandler } from "react-native-exception-handler";
setJSExceptionHandler((error, isFatal) => {
  // This is your custom global error handler
  // You do stuff like show an error dialog
  // or hit google analytics to track crashes
  // or hit a custom api to inform the dev team.
});

本机异常 正如我已经提到的,本机异常是由本机模块错误和内部本机反应本机代码产生的。

根据我的经验,与 Js 相比,我们通常会遇到很少的未捕获的 Native 异常,好消息是我们也将使用相同的库(react-native-exception-handler)来处理本机异常,但你不能显示 JS警报框或通过 JS 代码执行任何 UI 操作。唯一的解决方案是显示库提供的本机警报,但如果您想自定义警报,则必须编写本机代码。

要为 Native 异常创建全局处理程序,您只需使用

setNativeExceptionHandler
函数注册您的处理程序,如下所示:

import { setNativeExceptionHandler } from "react-native-exception-handler";
const exceptionhandler = (exceptionString) => {
  // your exception handler code here
};
setNativeExceptionHandler(
  exceptionhandler,
  forceAppQuit,
  executeDefaultHandler
);

跟踪异常情况 处理异常而不跟踪它们是没有意义的,因为我们讨论的所有解决方案只能改善用户体验并向用户提供有关错误的更多信息,而不是白屏或应用程序崩溃。

Sentry是一个基于云的错误监控平台,可以帮助我们实时跟踪所有这些错误。通过创建一个免费帐户并安装react-native-sentry,您可以在处理程序(js 和 Native)中使用它来使用

captureException
发送堆栈错误,如下所示:

// ErrorHandler.js
import * as Sentry from "@sentry/react-native";
const myErrorHandler = (error: Error) => {
  Sentry.captureException(error);
};

现在,请务必纠正您的错误。


0
投票

我也遇到过和你一样的情况;当我将错误处理代码放入 App.js 文件中时,它不起作用,但是当我将其放入 index.js 文件中时,它起作用了。但是,它仍然无法捕获代码 throw new Error('Some message') 抛出的错误。

© www.soinside.com 2019 - 2024. All rights reserved.