-
Notifications
You must be signed in to change notification settings - Fork 50.5k
Description
Do you want to request a feature or report a bug?
Bug
What is the current behavior?
Basically 3 levels of components
App
Shell
Header
view // "children" via react-router
Footer
Shell.tsx (catches)
class Shell extends React.Component {
state: ShellState = {
alerts: [],
}
componentDidCatch(err, info) {
const alert = new Alert(err);
this.setState({ alerts: _.concat(alerts, alert) });
debugger; // all good in the neighbourhood
}
render() {
return (
<React.Fragment>
<Header alerts={this.state.alerts} />
{this.props.children}
<Footer />
</React.Fragment>
);
}
}SomeView.tsx (always throws in render)
class SomeView extends React.Component {
// …
render() {
throw new Error('test');
}
}Shell.componentDidCatch() fires and does its thing (no new errors thrown), but the app still unmounts anyway.
I understand why this is happening: SomeView's render always throws an error, so after the componentDidCatch handles the error and Shell re-renders, SomeView throws again, and apparently React shuts down (probably as an easy way to avoid an endless loop).
What is the expected behavior?
App does not unmount; abort/blacklist/ignore the miscreant component (which could be N-levels deep in the app).
I expect it to work like the codepen example.
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
No, before v16 React did not explode (to use less colourful language than this deserves).
react 16.3.1
This componentDidCatch is both neat and horrendous:
- Neat in that there is a (mostly) standard way to catch and handle errors.
- Horrendous in that it unmounts the entire app, creating an unrecoverable state (have you seen Spotify lately?). If anything, the unmounting should be a development-only bug-pretending-to-be-a-feature that can be disabled (because this is hella annoying and any cursory google search on it clearly shows countless hours wasted).