Search code examples
javascriptreduxasync-awaitnext.jsaxios

Unhandled Runtime Error AxiosError: Request failed with status code 401 in next.js


I am using Next.js. I have created an Axios interceptor where a rejected Promise will be returned. But where there is a server-specific error that I need. Next.js is showing the error in the application like this.

enter image description here

And there is the code of the Axios interceptor and instance.

import axios from "axios";
import store from "../redux/store";
import getConfig from 'next/config';
const { publicRuntimeConfig } = getConfig();

let token = "";
if (typeof window !== 'undefined') {
  const item = localStorage.getItem('key')
  token = item;
}
const axiosInstance = axios.create({
  baseURL: publicRuntimeConfig.backendURL,
  headers: {
    Authorization: token ? `Bearer ${token}` : "",
  },
});

axiosInstance.interceptors.request.use(
  function (config) {
    const { auth } = store.getState();
    if (auth.token) {
      config.headers.Authorization = `Bearer ${auth.token}`;
    }
    return config;
  },
  function (error) {
    return Promise.reject(error);
  }
);

axiosInstance.interceptors.response.use(
  (res) => {
    console.log(res)
    return res;
  },
  (error) => {
    console.log(error)
    return Promise.reject(error);
  }
);

export default axiosInstance;

Also, I am using redux and there is the action.

import axios from "../../api/axios";
import { authConstants } from "../types";

export const login = (data) => {
  return async (dispatch) => {
    try {
      dispatch({
        type: authConstants.LOGIN_REQUEST,
      });
      const res = axios.post("/user/login", data);
      if (res.status === 200) {
        dispatch({
          type: authConstants.LOGIN_SUCCESS,
          payload: res.data,
        });
      }
    } catch (error) {
      console.log(error, authConstants);
      dispatch({
        type: authConstants.LOGIN_FAILURE,
        payload: { error: error.response?.data?.error },
      });
    }
  };
};

Solution

  • Your problem is here...

    const res = axios.post("/user/login", data);
    

    You're missing await to wait for the response

    const res = await axios.post("/user/login", data);
    

    This fixes two things...

    1. Your code now waits for the response and res.status on the next line will be defined
    2. Any errors thrown by Axios (which surface as rejected promises) will trigger your catch block. Without the await this does not happen and any eventual promise failure bubbles up to the top-level Next.js error handler, resulting in the popup in your screenshot.