Centralizing API error handling in React apps

In this article I'm going to present to you a way of handling your API errors once and for all in a centralized and easily extendable way, regardless of the state-management library (Redux, Apollo, etc.) that you are using.

Almost every modern app interacts with an API for their data requirements; be it a RESTful API or a GraphQL one, firing requests on the web is the bread and butter of the majority of apps out there. Most of the times things go well and your request is returns successfully, but there are times when things don't go as smoothly. I'm talking about those dreaded 404s, 403s & 500s that the APIs can return, which in turn, have to be presented to the user. Due to the nature of these kind of responses, handling them all in a single place would be ideal.

Unfortunately, managing that in a React app has been harder than it should, with different completely approaches from app to app. In this article I'm going to present to you a way of handling your API errors once and for all in a centralized and easily extendable way, regardless of the state-management library (Redux, Apollo, etc.) that you are using. Moreover, the approach that we'll take can be re-used into all of your apps, regardless of whether you are implementing client or server-side rendering. So without further ado, let's dig straight in.

Setting the scene

For the purposes of this article, I'll assume the presence of a RESTful API with the usual HTTP error status codes, but similar concepts apply to a GraphQL and any other API. I'll also assume the use of react-router , but the exact same concepts apply for @reach/router or any other React routing library.

Let's say we want to write a small app that's going to have 2 pages. The first page is going to show us a list of dog breeds. When we click on a breed, we'll be redirected to this breed's page, which will display a random photo of a dog of that breed. The app would look like this (don't worry too much about the code or the UI, since it's outside the scope of this article) :

Our app works, but we haven't handled the 404 case yet. When the users visit a page that doesn't exist, we want to show them our very own 404 page with the text "Four:oh:four". This page should be shown in the following two scenarios:

  • The user visits an invalid URL regex (i.e. /cats/husky/).

  • The user visits a valid URL regex but with an invalid breed (this can happen if the user manually tweaks the URL from the address bar).

The first case is easy to handle. Like most tutorials out there recommend, we'll just add a "catch-all" route as the last route of our app and we will wrap all of our routes with react-router's <Switch /> component. This would look something like this: