最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - componentDidCatch + window.addEventListener('error', cb) don't behave as expected - Stack O

programmeradmin5浏览0评论

I have a ponentDidCatch error boundary on my root ponent, to render a nice error page in case something terrible happens.

But I also have a window.addEventListener('error', cb) event handler, in case something even worse happens (outside React).

My issue now is that whenever ponentDidCatch gets an error, the window error handler gets it too, so I always end up with the worst case scenario error handling, rather than the "in-react" one.

Also, it looks like the global error handler is triggered before the React error boundary, so it's not possible to mark an error as "handled" so that I can manually ignore it later.

Here's a CodePen showing my issue:

A minimal code example would be:

class App extends React.Component {
  ponentDidCatch(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

On the contrary, with just JavaScript, the local error handler would prevent the error from reaching the window error handler.

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

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

Is this expected behavior? Can you think of a way to make it work as I'd like it to?

I have a ponentDidCatch error boundary on my root ponent, to render a nice error page in case something terrible happens.

But I also have a window.addEventListener('error', cb) event handler, in case something even worse happens (outside React).

My issue now is that whenever ponentDidCatch gets an error, the window error handler gets it too, so I always end up with the worst case scenario error handling, rather than the "in-react" one.

Also, it looks like the global error handler is triggered before the React error boundary, so it's not possible to mark an error as "handled" so that I can manually ignore it later.

Here's a CodePen showing my issue:
https://codepen.io/FezVrasta/pen/MNeYqN

A minimal code example would be:

class App extends React.Component {
  ponentDidCatch(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

On the contrary, with just JavaScript, the local error handler would prevent the error from reaching the window error handler.

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

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

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

Is this expected behavior? Can you think of a way to make it work as I'd like it to?

Share Improve this question edited Jul 25, 2019 at 9:08 Fez Vrasta asked Jul 25, 2019 at 8:51 Fez VrastaFez Vrasta 14.9k24 gold badges109 silver badges176 bronze badges 9
  • Your code typically behaves as it should be! ponentDidCatch and the eventListener you have attached to the document will catch the same errors, and this is what they currently do, they behave as the program expects, but out to your expectations you are not, I was wondering, what is actual scenario that the eventListener catches, while ponentDidMount won't? – Sultan H. Commented Jul 25, 2019 at 9:04
  • 2 @SultanH. I wouldn't expect the errors handled/caught by ponentDidCatch to bounce up to window, since they are handled in the React ponent. The React error boundary only catches errors happening in the render phase, while the window error handler will catch any other unhandled error (theoretically) – Fez Vrasta Commented Jul 25, 2019 at 9:05
  • Great, I had a look to your ErrorBoundry ponent, I will refactor the problem, which is in there, and let you know what changed in a bit of time. – Sultan H. Commented Jul 25, 2019 at 9:08
  • Could you register listener in ponentDidMount of Boundary ponent and then you can store handled errors in state? – zhuber Commented Jul 25, 2019 at 9:11
  • @zhuber I really need the most broad error handling logic possible, to catch anything even not related to React. But if you want to post an answer with an example of what you mean it'd be great. – Fez Vrasta Commented Jul 25, 2019 at 9:12
 |  Show 4 more ments

1 Answer 1

Reset to default 8

Seems like this is just a development behaviour. Please take a look at this ment

In development environment, React uses a trick: caught exceptions are thrown inside a fake DOM event which makes them reported by window.onerror, but then React actually catches them so that they don't propagate up (in case there is an error boundary — otherwise they are rethrown).

In production errors caught by error boundaries stay caught.

I've just tested your example in production and alert does not show when error is thrown in render method.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论