componentDidCatch + window.addEventListener('error',cb)的行为不符合预期

时间:2019-07-25 08:51:37

标签: javascript reactjs error-handling

我在根组件上有一个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'))

这是预期的行为吗?您能想到一种让它如我所愿地工作的方法吗?

1 个答案:

答案 0 :(得分:3)

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

  

在开发环境中,React使用一个技巧:捕获的异常是   抛出一个伪造的DOM事件,使它们被报告   window.onerror,但是后来React实际上捕获了它们,因此它们   不要向上传播(如果存在错误边界,否则   他们被扔掉了。

     

在生产中,由于错误边界而捕获的错误仍然存​​在。

我刚刚在production中测试了您的示例,当alert方法中抛出error时,render不会显示。