Rsnarsna's picture
Upload 44 files
b0c3c39 verified
import axios from 'axios';
import qs from 'qs';
const instance = axios.create({
baseURL: process.env.REACT_APP_API_URL || 'http://localhost:8000',
headers: {
'Content-Type': 'application/json',
},
});
// Token refresh mechanism
let isRefreshing = false;
let failedQueue: any[] = [];
const processQueue = (error: any, token: string | null = null) => {
failedQueue.forEach(prom => {
if (error) {
prom.reject(error);
} else {
prom.resolve(token);
}
});
failedQueue = [];
};
// Add a request interceptor
instance.interceptors.request.use(
(config) => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
// Handle form data
if (config.data instanceof FormData) {
config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
config.data = qs.stringify(Object.fromEntries(config.data));
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
// Add a response interceptor
instance.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config;
if (error.response?.status === 401 && !originalRequest._retry) {
if (isRefreshing) {
return new Promise((resolve, reject) => {
failedQueue.push({ resolve, reject });
})
.then(token => {
originalRequest.headers.Authorization = `Bearer ${token}`;
return instance(originalRequest);
})
.catch(err => Promise.reject(err));
}
originalRequest._retry = true;
isRefreshing = true;
try {
const refreshToken = localStorage.getItem('refreshToken');
if (!refreshToken) {
throw new Error('No refresh token available');
}
const response = await axios.post('/api/auth/refresh', {
refresh_token: refreshToken,
});
const { access_token, refresh_token } = response.data;
localStorage.setItem('token', access_token);
localStorage.setItem('refreshToken', refresh_token);
instance.defaults.headers.common.Authorization = `Bearer ${access_token}`;
processQueue(null, access_token);
return instance(originalRequest);
} catch (refreshError) {
processQueue(refreshError, null);
localStorage.removeItem('token');
localStorage.removeItem('refreshToken');
window.location.href = '/login';
return Promise.reject(refreshError);
} finally {
isRefreshing = false;
}
}
return Promise.reject(error);
}
);
// Error handling utility
export const handleApiError = (error: any): string => {
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
return error.response.data.message || 'An error occurred while processing your request';
} else if (error.request) {
// The request was made but no response was received
return 'No response received from server. Please check your internet connection';
} else {
// Something happened in setting up the request that triggered an Error
return error.message || 'An unexpected error occurred';
}
};
export default instance;