I am using interceptor that refreshes the access token upon a status code of 401
but my catch
has stopped working upon any other error codes such as 400
request.js
import axios from 'axios' const axiosApiInstance = axios.create() axiosApiInstance.interceptors.response.use( (response) => { return response }, (error) => { return new Promise((resolve) => { const originalRequest = error.config const refreshToken = localStorage.getItem("refresh") if (error.response && error.response.status === 401 && error.config && !error.config.__isRetryRequest && refreshToken) { originalRequest._retry = true const response = fetch('http://127.0.0.1:8000/api/token/refresh/', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ refresh: refreshToken, }), }) .then((res) => res.json()) .then((res) => { localStorage.setItem("access", res.access) originalRequest.headers['Authorization'] = 'Bearer ' + res.access return axios(originalRequest) }) resolve(response) } return Promise.reject(error) }) }, ) export default axiosApiInstance
Advertisement
Answer
You need to pass a second argument to your callback to new Promise
called reject
and then reject the promise using that function instead of Promise.reject
.
I can’t verify without testing, and that’s a bit difficult to set up right now, but it looks very much like you’re not properly rejecting the promise that you’re returning from the error callback. If you can confirm that the promise is never resolved or rejected in the case of a 400
, that would help confirm my suspicion. Try making this change, though:
The arguments to your new Promise callback:
return new Promise((resolve) => {
becomes
return new Promise((resolve, reject) => {
and later to reject, instead of
return Promise.reject(error)
just do this
reject(error) // return does nothing here, can be omitted
Edit:
Although, a very good point by someone that this is a promise anti-pattern. You’re creating a new Promise for no reason.
import axios from 'axios' const axiosApiInstance = axios.create() axiosApiInstance.interceptors.response.use( (response) => { return response }, (error) => { const originalRequest = error.config const refreshToken = localStorage.getItem("refresh") if (error.response && error.response.status === 401 && error.config && !error.config.__isRetryRequest && refreshToken) { originalRequest._retry = true return fetch('http://127.0.0.1:8000/api/token/refresh/', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ refresh: refreshToken, }), }) .then((res) => res.json()) .then((res) => { localStorage.setItem("access", res.access) originalRequest.headers['Authorization'] = 'Bearer ' + res.access return axios(originalRequest) }) } return Promise.reject(error) }, ) export default axiosApiInstance
Should be something like this.