[React] Routing to an Error Page with axios interceptors

Recently, I came across a user story where the frontend routes to an Error Page when it fails to communicate with the backend.

GIVEN as 000 as user of this product
WHEN navigating to a different page
THEN I can see an error page when data was not fetched successfully

On top of that, users can go back to the previous page to retry.

GIVEN as 000 as user of this product and
I am currently on the error page
WHEN I click 'Go Back' button
THEN I can go back to the previous page to use this product again

In order to implement this,

  1. handle errors in catch block
  2. use axios interceptors to intercept responses before they are handled by then or catch

For simplicity, I will route to an error page when the status is 404.

First Attempt

First attempt was to redirect to an error page using window.location.

However, with this approach the states stored on the frontend gets lost because window.location causes a reload according to this Stack Overflow answer.

From this experiment, I learned that I had to use navigate from react-router-v6 in order to maintain the states. Then, the challenge was about how to use useNavigate hook outside of React components.

Second Attempt

Second attempt was to handle errors in try-catch. With this approach, React components using this HttpClient.get() will have to pass in a callback function for routing.

Then, the page calling HttpClient would look like this. This would be adequate if each React Component needs to route to different error pages. However, normally different error pages are meant for different error statuses.

Final Implementation with Unit Tests

We have most of it working, the final attempt was to merge the good sides of past attempts and to refactor. I liked the idea of using interceptors more because then all axios requests work the same way and the page components making these requests don’t need to worry about the callbacks.

HttpClient

Here is the test code to verify that HttpClient will work the way it is intended. This demonstrates how to unit test axios interceptors.

App

In the App.js, the interceptors need to be set up. index.js could be a better place to set up one thing because App.js will run every time when a different page is rendered. To ensure that the interceptors are set up once, a boolean state was used.

ProductDetailPage

All the navigate callbacks from the page component seen in the second attempt are now gone because the callback is provided in App.js.

ErrorPage

Of course, the error page needs to have a button to go back to the previous page.

Tests for the error page:

Integration Tests

Lastly, here are some integration tests to cover user journeys.

Happy Path

Happy(?) Path with Error Page

This test is to cover the entire flow where user starts off happy but then sees the error page with an error. Then user can click “Go Back” button to retry from the UI.

This article covered

  1. How to use axios interceptors to handle specific errors
  2. How to unit test axios interceptors
  3. How to integrate test with axios interceptors

Full source can be found at:

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store