Search code examples
reactjsreact-nativeaxiostry-catch

Axios request intercepted by interceptor not falling in catch block from initial request if error is Promise.rejected in interceptor


I'm trying to handle some request errors using axios interceptors to better provide messages to the catch block which displays a toast in my application. But no matter what article, tutorial, video, or documentation I see they use return Promise.reject(error) to return the error in the interceptor. That does not work in my case, I'm working on react native project, so I thought it could be a problem of framework, but I managed to reproduce it on Code Sandbox.

CodeSandbox Working Example: https://codesandbox.io/s/pedantic-antonelli-s4iih0?file=/src/services/api.ts:85-86

This is the Axios interceptors documentation https://axios-http.com/docs/interceptors

Interceptors documentation screenshot

And here is my interceptor:

import axios from "axios";

import { AppError } from "../utils";

function errorHandler(requestError: unknown) {
  if (axios.isAxiosError(requestError)) {
    console.log("gets to the interceptor");
    if (requestError.response && requestError.response.data) {
      switch (requestError.response.status) {
        case 400:
          return Promise.reject(requestError);

        case 401: {
          return Promise.reject(new AppError("Failed to authenticate token."));
        }

        case 404:
          if (requestError.response.config.url?.includes("api")) {
            // return Promise.reject(new AppError('Email or password invalid'));
            throw new AppError("Email ou senha inválidos.");
          }

          return Promise.reject(requestError);

        default:
          return Promise.reject(requestError);
      }
    }
    return Promise.reject(requestError);
  }
  return Promise.reject(requestError);
}

export const api = axios.create();

api.interceptors.response.use(
  (response) => {
    return response;
  },
  (requestError) => {
    errorHandler(requestError);
  }
);

Here is my request function:

  const handleSubmit2 = async () => {
    try {
      console.log("submit start 2");
      const data = await api.post("/api/not-movies-again", {
        email: "wow@email.com",
        password: "wow password"
      });
      console.log("REQUEST DATA 2: ", data);
    } catch (error) {
      console.log("Catcher ERROR 2: ", error);
    } finally {
      console.log("submit end 2");
    }
  };

Not a single return Promise.reject(error) falls in the catch block. It turns out after hours hitting my head on this, I had the idea of throwing the error itself instead of rejecting it and it actually worked, the error fall in the catch block.

I could just be really dumb, but am I doing anything crazy wrong here? Am I hitting an edge case by simply handling my errors? Or is the documentation and every tutorial outdated?


Solution

  • I think you just forgot a return there:

    api.interceptors.response.use(
      (response) => {
        return response;
      },
      (requestError) => {
        // Here probably need to have a return
        return errorHandler(requestError);
      }
    );