【问题标题】:componentDidCatch + window.addEventListener('error', cb) don't behave as expectedcomponentDidCatch + window.addEventListener('error', cb) 未按预期运行
【发布时间】:2019-12-03 11:51:21
【问题描述】:

我的根组件上有一个componentDidCatch 错误边界,以便在发生可怕的事情时呈现一个漂亮的错误页面。

但我也有一个 window.addEventListener('error', cb) 事件处理程序,以防更糟糕的事情发生(在 React 之外)。

我现在的问题是,每当componentDidCatch 出错时,window 错误处理程序也会出错,所以我总是以最坏情况下的错误处理结束,而不是“反应中”的错误处理。

此外,看起来全局错误处理程序是在 React 错误边界之前触发的,因此无法将错误标记为“已处理”,以便我以后可以手动忽略它。

这是一个显示我的问题的 CodePen:
https://codepen.io/FezVrasta/pen/MNeYqN

一个最小的代码示例是:

class App extends React.Component {
  componentDidCatch(err) {
    console.log('react handled error', err);
  }
  render() {
    return 'foobar';
  }
}

window.addEventListener('error', err => console.log('global error', err));

// on error, I get:
// 'global error', err
// 'react handled error', err

相反,仅使用 JavaScript,本地错误处理程序会阻止错误到达窗口错误处理程序。

https://codepen.io/FezVrasta/pen/eqzrxO?editors=0010

try {
  throw new Error('error');
} catch (err) {
  alert('scoped error');
}

window.addEventListener('error', () => alert('global error'))

这是预期的行为吗?你能想出一种方法让它按我的意愿工作吗?

【问题讨论】:

  • 您的代码通常表现得应该是这样! componentDidCatch 和您附加到 documenteventListener 将捕获相同的错误,这就是它们目前所做的,它们的行为与程序预期的一样,但出乎你的意料,你不是,我想知道,eventListener 捕获而 componentDidMount 不会捕获的实际场景是什么?
  • @SultanH。我不希望componentDidCatch 处理/捕获的错误反弹到window,因为它们是在 React 组件中处理的。 React 错误边界仅捕获渲染阶段发生的错误,而window 错误处理程序将捕获任何其他未处理的错误(理论上)
  • 太好了,我查看了您的 ErrorBoundry 组件,我将重构其中的问题,稍后让您知道发生了什么变化。
  • 能否在Boundary组件的componentDidMount中注册监听器,然后你可以在状态中存储处理过的错误?
  • @zhuber 我真的需要尽可能广泛的错误处理逻辑,以捕捉任何与 React 无关的东西。但是,如果您想用一个例子来说明您的意思,那就太好了。

标签: javascript reactjs error-handling


【解决方案1】:

似乎这只是development 的行为。请看this comment

在开发环境中,React 使用了一个技巧:捕获的异常是 扔在一个虚假的 DOM 事件中,这使得它们被报告 window.onerror,但是 React 实际上会捕获它们,以便它们 不要向上传播(如果存在错误边界 - 否则 它们被重新抛出)。

在生产中被错误边界捕获的错误仍然被捕获。

我刚刚在production 中测试了您的示例,当errorrender 方法抛出时,alert 没有显示。

【讨论】:

  • 这是一个非常有用的信息!它应该在文档中! (我会发 PR)
  • 这个答案解释了意外的行为,但我仍然试图弄清楚如何区分和处理 React 之外的错误,因为在开发中将调用全局错误处理程序来处理 React 错误。
  • 我打开了一个问题来讨论是否有办法让错误在生产和开发中表现一致:github.com/facebook/react/issues/19613
猜你喜欢
  • 2014-11-12
  • 1970-01-01
  • 2020-06-28
  • 2012-02-18
  • 2018-01-18
  • 2012-06-14
  • 2019-03-03
  • 2012-09-21
  • 2014-07-19
相关资源
最近更新 更多