Back

Error handling in functional components

This examples walks through a series of different situations in which an error may be thrown, explores what happens, and what can be done about it.

Each card has a link to its source code (on GitHub) at the top, as well as a summary of the setup.

Problem 1: errors in components w/o promises

Errors thrown in components will cause the page to crash. React has a standard solution to this: Error Boundaries

Throw inside component
  • No error boundary
  • Destroys page
  • Only recovery is to refresh
Throw Error
Throw in useEffect
  • No error boundary
  • Destroys page
  • Only recovery is to refresh
Throw Error
Throw inside component
  • Error boundary
  • Prints to console in development
  • Error fully handled 👌
Throw Error
Throw in useEffect
  • Error boundary
  • Prints to console in development
  • Error fully handled 👌
Throw Error

Problem 2: errors in components in promises

However, Error Boundaries do not work for async functions/promises.

Throw in promise in component
  • Error boundary
  • Same as w/o error boundary
  • Does not destroy the view
  • Completely unhandled
  • Shows up in console
Throw Error
Throw inside promise in useEffect
  • Error boundary
  • Same as w/o error boundary
  • Does not destroy the view
  • Completely unhandled
  • Shows up in console
Throw Error

Solution 1: react-error-boundary package

Throw inside promise in useEffect
  • Uses an npm package
  • See react-error-boundary (vs native react)
  • Prints to console in development
  • Error fully handled 👌
  • Works with ErrorBoundary pattern
  • Avoids global state/handlers
  • Only works inside components
  • Which for some use cases implies repeat code
Throw Error

Solution 2: global event system

Throw inside promise in useEffect
  • Uses JavaScript's built in global event system
  • Allows generic error handling
  • Error fully handled 👌
  • Works well to DRY repeat errors
  • React handles errors from any JS/outside components
  • Completely self-managed
Throw Error

Conclusion

The hard problem in handling errors in functional components in React is dealing with errors from async functions/promises.

Two solutions are presented: via react-error-boundary and via a global event mechanism.

react-error-boundary can be a good way to take advantage of a standard global error handling mechanism on a per-component level.

However, for general-purpose tools (e.g. an internal http client that wraps a backend API) that exist outside of components, or that would benefit from not having to think about error handling each time - it may make sense to opt for a global event mechanism to tie the world of react with the outside world.