I have a componentDidCatch
error boundary on my root component, 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 componentDidCatch
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 {
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
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?
Seems like this is just a development
behaviour. Please take a look at this comment
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With