当前位置: 首页 > 知识库问答 >
问题:

你可以用try/catch块捕获React.js应用程序的所有错误吗?

酆英达
2023-03-14

我做了一个不实时运行的反应应用程序,使用它的人注意到偶尔会出现一些奇怪的错误。我不知道为什么或发生了什么,也无法重现它。

所以我想知道是否有一种方法可以将整个应用程序或其部分包装在try/catch块中,以便我可以将错误发送到服务器上的错误日志?

到目前为止,我所读到的只是,您可以将整个渲染函数包装在尝试/捕获中,但这不会由于用户交互而捕获任何错误,对吗?

共有3个答案

蒋浩
2023-03-14

您可以利用React的BatchingStrategyAPI轻松地将<code>try/catch<code>包装在所有React代码周围。此窗口的好处在于<code>窗口。onerror是,在所有浏览器中都可以获得很好的堆栈跟踪。即使是像Microsoft Edge和Safari这样的现代浏览器也不提供对window.onerror的堆栈跟踪。

以下是 React 15.4 的样子:

import ReactUpdates from "react-dom/lib/ReactUpdates";
import ReactDefaultBatchingStrategy from "react-dom/lib/ReactDefaultBatchingStrategy";

let isHandlingError = false;
const ReactTryCatchBatchingStrategy = {
  // this is part of the BatchingStrategy API. simply pass along
  // what the default batching strategy would do.
  get isBatchingUpdates () { return ReactDefaultBatchingStrategy.isBatchingUpdates; },

  batchedUpdates (...args) {
    try {
      ReactDefaultBatchingStrategy.batchedUpdates(...args);
    } catch (e) {
      if (isHandlingError) {
        // our error handling code threw an error. just throw now
        throw e;
      }

      isHandlingError = true;
      try {
        // dispatch redux action notifying the app that an error occurred.
        // replace this with whatever error handling logic you like.
        store.dispatch(appTriggeredError(e));
      } finally {
        isHandlingError = false;
      }
    }
  },
};

ReactUpdates.injection.injectBatchingStrategy(ReactTryCatchBatchingStrategy);

这里有完整的文字:https://engineering.classdojo.com/blog/2016/12/10/catching-react-errors/

郭永安
2023-03-14

这是我最后用的

编辑:React 16介绍了正确的方法来做到这一点,请参阅@goldyluck的回答。

  componentWillMount() {
    this.startErrorLog();
  }

  startErrorLog() {
    window.onerror = (message, file, line, column, errorObject) => {
      column = column || (window.event && window.event.errorCharacter);
      var stack = errorObject ? errorObject.stack : null;

      //trying to get stack from IE
      if (!stack) {
        var stack = [];
        var f = arguments.callee.caller;
        while (f) {
          stack.push(f.name);
          f = f.caller;
        }
        errorObject['stack'] = stack;
      }

      var data = {
        message: message,
        file: file,
        line: line,
        column: column,
        errorStack: stack
      };

      //here I make a call to the server to log the error

      //the error can still be triggered as usual, we just wanted to know what's happening on the client side
      return false;
    };
  }
罗晨
2023-03-14

React 16引入了错误边界和componentDidCatch生命周期方法:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  componentDidCatch(error, info) {
    // Display fallback UI
    this.setState({ hasError: true });
    // You can also log the error to an error reporting service
    logErrorToMyService(error, info);
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children;
  }
}

然后您可以将其用作常规组件:

<ErrorBoundary>
  <MyWidget />
</ErrorBoundary>

或者,您可以将根组件包装为npm包react-error-边界,并设置回退组件和行为。

import {ErrorBoundary} from 'react-error-boundary';

const myErrorHandler = (error: Error, componentStack: string) => {
  // ...
};

<ErrorBoundary onError={myErrorHandler}>
  <ComponentThatMayError />
</ErrorBoundary>
 类似资料:
  • 问题内容: 我制作了一个无法实时运行的React应用程序,使用它的人注意到,偶尔会出现一些奇怪的错误。我不知道为什么或发生什么,也无法复制它。 所以我想知道是否有一种方法可以将整个应用程序或其部分包装在try / catch块中,以便将错误发送到服务器上的错误日志中? 到目前为止,我所读到的只是可以将整个render函数包装在try / catch中,但是由于用户交互的原因而不会捕获任何错误吗?

  • 问题内容: 我试图确保用户输入是整数,但是当我使用下面的代码时,我只会得到语句的无限循环。关于如何改进的任何建议? 问题答案: 不会消耗无效的输入,因此它将反复尝试读取相同的无效值。要解决此问题,您需要通过调用或接受任何值来显式使用它。 顺便说一句,为使您的代码更整洁并避免昂贵的操作(如创建异常),您应使用。 这是组织代码的方法

  • 我正在尝试将错误捕获添加到组件的渲染函数中。当我在实际的渲染函数中抛出错误时,这可以正常工作,但是如果组件的子级中存在错误,则尝试不会捕获错误(或者它们被子组件错误处理程序拦截,我不确定? 是否存在将错误强制到父级的方法。 上述工作 这上面不抓

  • 我开始在javascript对象中添加错误处理,这些对象通常使用jQuery。我的问题是,当我从jQuery方法中抛出新错误时-它不会被包装jQuery调用的catch语句捕获-它只是抛出标准错误,但不会作为日志消息登录到控制台。下面是一个例子: 当我用try/catch包装回调函数的内容时,它就可以工作了: 有什么想法可以简化它,为什么会这样?

  • Player类如下所示: 前面的main方法(它使用多个扫描器,包括try-with-recours,没有任何错误或异常)如下所示:

  • 本文向大家介绍一个try块在Java中可以有多个catch块吗?,包括了一个try块在Java中可以有多个catch块吗?的使用技巧和注意事项,需要的朋友参考一下 是的,单个try块可以有多个catch块。 示例 以下Java程序包含一个数字数组(显示)。从用户那里,它接受此数组中的两个位置,然后将第一个位置的数字除以第二个位置的数字。 输入值时- 如果选择的位置不在显示的数组中,则抛出Array