Catching exceptions using Higher Order Components in React 16

As you might already know, React 16 beta is out and it ships with a full internal rewrite of the React core (a.k.a Fiber), providing several new features. Though in this post we will only talk about new method on React.Component: componentDidCatch. It basically catches JavaScript errors anywhere in child component tree, like wrapping the children in a big try/catch block. You can find out about it more in this post by Dan Abramov.

Most of the people using React 16 would be ones upgrading from previous versions. So it would be impractical to rewrite the whole component libraries to provide error handling, others may prefer having their views to be “dumb” and represent the UI solely without extra logic. So the better way to go would be wrapping components, reusing wrappers and avoiding modifying the component definitions.

So we need to implement this new error handling feature so that:

  1. We can display fallback components (views) when the errors happen
  2. We avoid coupling of normal and fallback components
  3. We can easily report errors to some service
  4. We have ability to reuse reporting or fallback logic

Naive, less practical approach would be to do it like this:

We could make this slightly better if we parameterize ErrorHandler and instead of calling reportErrorToService directly pass error reporter function as a prop and instead of returning inline fallback view (line 12) we pass a component. Though, we would still have to update our component definitions in order to wrap some parts of our UI into ErrorHandler tags. But as we already discussed, we don’t want to modify our component libraries, we want to just decorate them.

To accomplish this, we could use Higher Order Components:

We have this withErrorHandler HOC (We’ll talk about the implementation later), which takes error reporter as callback and fallback component and in case of error, calls the callback and renders the fallback component. We can wrap any component using it and the component will get the error handling, without changing it’s definition, without touching the JSX views.

We can make it even prettier, we will probably have one service for error reporting and display mostly the same views as fallback components. So we can export partially applied withErrorHandler HOC like this:

and then use it to export wrapped components, instead of just components:

This way we can easily add error handling logic to our components and what is also important, we can also easily remove it!

So how does the withErrorHandler HOC work? Actually, its quite easy to implement:

This higher order component can wrap any component in your codebase and catch all the exceptions in the tree. You might want to wrap whole page in it, so that if anything on the page throws, the whole page will render fallback component, you can wrap individual components which are mission critical or you can do both!

You might have noticed that in the above snippet, withErrorHandler takes 3 arguments, in the final version it is curried, you can find full source with demo and more usage examples in the repository.

I hope you enjoyed the article and liked my approach, if so you can star the project and follow me on medium ❤️

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.