Home > Net >  Axios : error handled by interceptor but still rejected
Axios : error handled by interceptor but still rejected

Time:07-10

I am building a jwt token refresh logic (refresh the authentication token when it expires) with axios interceptors. The refresh part works well : axios intercepts the error, refreshes the token, and retries the request (and successfully gets an answer from the server).

However, the page that made the request that failed because of the expired token still catches the error. I feel like axios still returns the error to the function that made the call instead of just returning the retried request, but idk how.

Here is the code in my axios.js file :

import { boot } from "quasar/wrappers";
import axios from "axios";
import * as storage from "../helpers/storage";
import store from "../store/index.js";
import router from "../router/index.js";

const api = axios.create({
  baseURL: process.env.API_URL,
  crossdomain: true,
  headers: {
    "Content-Type": "application/json",
    Accept: "application/json",
  },
});

api.interceptors.request.use(
  function (config) {
    if (config.url !== "/register") {
      const accessToken = storage.getAccessToken();
      if (accessToken) {
        config.headers.Authorization = "Bearer "   accessToken;
      }
    }
    return config;
  },
  function (error) {
    // Do something with request error
    return Promise.reject(error);
  }
);

api.interceptors.response.use(
  function (response) {
    // Any status code that lie within the range of 2xx cause this function to trigger
    // Do something with response data
    return response;
  },
  function (error) {
    // Any status codes that falls outside the range of 2xx cause this function to trigger
    // Do something with response error
    if (error.response.data.message === "Expired JWT Token") {
      const originalRequest = error.config;
      api
        .post("/token/refresh", { refresh_token: storage.getRefreshToken() })
        .then(({ data }) => {
          if (data !== undefined) {
            storage.setTokens(data.token, data.refresh_token);
          }
          originalRequest.headers = { Authorization: `Bearer ${data.token}` };

          return new Promise(() => {
            axios.request(originalRequest).then((response) => {
              return response;
            });
          });
        })
        .catch((error) => {
          console.error(error);
        });
    } else if (error.response.data.message === "Invalid JWT Token") {
      console.log("error");
      store()
        .dispatch("auth/logout")
        .then(() => {
          router().push({
            name: "register-login",
            query: { error: "invalid_token" },
          });
          router().go(0);
          store().dispatch("setLoading", false);
        });
    } else {
      return Promise.reject(error);
    }
  }
);

export default boot(({ app }) => {
  // for use inside Vue files (Options API) through this.$axios and this.$api

  app.config.globalProperties.$axios = axios;
  // ^ ^ ^ this will allow you to use this.$axios (for Vue Options API form)
  //       so you won't necessarily have to import axios in each vue file

  app.config.globalProperties.$api = api;
  // ^ ^ ^ this will allow you to use this.$api (for Vue Options API form)
  //       so you can easily perform requests against your app's API
});

export { axios, api };

And here is an example of a request I do :

export function sendTags(context, payload) {
  return new Promise((resolve, reject) => {
    api
      .post("/spot/addTags", payload)
      .then(({ data }) => {
        resolve(data);
      })
      .catch((error) => {
        reject(error.response.data);
      });
  });

Any idea of what could be going wrong ?

CodePudding user response:

You didn't return a success result in the error function of response interceptor.

api.interceptors.response.use(
  function (response) {
    return response;
  },
  function (error) {
    if (error.response.data.message === "Expired JWT Token") {
      

     // You didn't return here!

     // change to:
      return api.post()
          .than(() => {

            // resolve the final result here
            return axios.request(originalRequest)
          })
    
    }
  }
)
  • Related