Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does routing stop working even when using an ErrorBoundary?

Our app use an ErrorBoundary to catch errors. This works fine and it presents an error message at the defined place, as it should. But after the error has manifested itself routing stops working, essentially breaking the app!

I find it a bit strange, considering that the app otherwise seems to work: DevTools shows routing/LOCATION_CHANGED actions being dispatched (I'm listening to the history object) when I click links and/or use the back button, and the url is updated, but no new routes/screens are being rendered.

Since React and Redux is working, I've come to point at React Router, since it's the main component dealing with routing. Does anyone know how I can stop it from breaking?

An example error

This error is from a connected component and happens in the mapStateToProps

connectAdvanced.js?fe33:242 Uncaught TypeError: Cannot read property '3528' of undefined
    at getUserInRoleById (VM7787 users-reducer.js:108)
    at getUserByUserInRoleId (VM7787 users-reducer.js:110)
    at Function.mapStateToProps [as mapToProps] (VM8180 EncounterNotesHistoryItem.jsx:360)

Followed by

The above error occurred in the <Connect(EncounterNotesHistoryItem)> component:
    in Connect(EncounterNotesHistoryItem)
    in div
    in Unknown (created by WithStyles(Component))
    in WithStyles(Component) (created by EncounterNotesHistory)
    in div (created by EncounterNotesHistory)

Component hierarchy (selected pieces)

App.jsx

<Provider store={store}>
  <ConnectedRouter history={customHistory} dispatch={dispatch}>
    <ErrorBoundary>
      <Route exact path="/appinfo" component={AppInfoScreen} />
      <Redirect exact from="/" to={`/encounter?attenderId=${userId}`} />
      <Route exact path="/search" component={SearchScreen} />
      <Route exact path="/search/:searchText" component={SearchScreen} />
      // and so on
    </ErrorBoundary>
  </ConnectedRouter>
</Provider>

Dependencies

"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-redux": "^5.0.7",
"react-router": "^5.0.1",
"react-router-dom": "^5.0.1",
"redux": "^3.6.0",
"reselect": "^3.0.1",
like image 672
oligofren Avatar asked Nov 30 '25 16:11

oligofren


1 Answers

The idea behind Error boundaries is to provide an elegant way to deal with cryptic errors.

Error boundaries work like a JavaScript catch {} block, but for components.

This means that everytime an error is thrown inside a component's tree that is wrapped by an Error boundary the whole tree will be replaced by the fallback value (a custom error message for example). So everytime one of your Route components throws an error the whole tree will be considered with error and will no longer be rendered (unmounted).

You could wrap individual Routes in an error boundary to protect them from crashing the rest of the application (including the other Routes).

See more about the ideal granularity of your Error boundaries here

like image 186
Dupocas Avatar answered Dec 02 '25 07:12

Dupocas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!