File size: 4,932 Bytes
25f22bf baaf93b 74728f5 baaf93b 25f22bf baaf93b 25f22bf baaf93b 74728f5 baaf93b 25f22bf baaf93b 25f22bf baaf93b 25f22bf baaf93b 25f22bf baaf93b 25f22bf baaf93b 25f22bf baaf93b 25f22bf baaf93b 25f22bf baaf93b 25f22bf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
import axios from 'axios';
import cookieService from '../services/cookieService';
// Create axios instance with default config
const API_BASE_URL = import.meta.env.VITE_API_URL ||
(import.meta.env.VITE_NODE_ENV === 'production' ?
'https://zelyanoth-lin-cbfcff2.hf.space' :
'http://localhost:5000');
console.log('API_BASE_URL:', API_BASE_URL);
// Ensure API_BASE_URL ends with /api for consistency
const normalizedBaseUrl = API_BASE_URL.endsWith('/api') ? API_BASE_URL : `${API_BASE_URL}/api`;
const apiClient = axios.create({
baseURL: normalizedBaseUrl,
timeout: 30000,
headers: {
'Content-Type': 'application/json',
},
withCredentials: true, // Send cookies with requests
});
// Request interceptor to add auth token
apiClient.interceptors.request.use(
async (config) => {
// Enhanced logging for debugging
const isDevelopment = import.meta.env.VITE_NODE_ENV === 'development';
if (isDevelopment) {
console.log('π [API Request]', {
method: config.method?.toUpperCase(),
url: config.baseURL + config.url,
headers: config.headers,
data: config.data
});
}
// Get token from cookie service with fallback to localStorage
let token = null;
try {
const tokens = await cookieService.getAuthTokens();
token = tokens?.accessToken;
} catch (error) {
console.warn('πͺ [Cookie] Error getting auth tokens, trying localStorage:', error.message);
token = localStorage.getItem('token');
}
if (token) {
config.headers.Authorization = `Bearer ${token}`;
if (isDevelopment) {
console.log('π [Token] Added token to request headers');
}
} else {
if (isDevelopment) {
console.log('π [Token] No token found for request');
}
}
return config;
},
(error) => {
console.error('β [API Request Error]', error);
return Promise.reject(error);
}
);
// Response interceptor to handle token refresh and errors
apiClient.interceptors.response.use(
(response) => {
// Enhanced logging for debugging
const isDevelopment = import.meta.env.VITE_NODE_ENV === 'development';
if (isDevelopment) {
console.log('β
[API Response]', {
status: response.status,
method: response.config.method?.toUpperCase(),
url: response.config.baseURL + response.config.url,
data: response.data
});
}
return response;
},
async (error) => {
const isDevelopment = import.meta.env.VITE_NODE_ENV === 'development';
const originalRequest = error.config;
// Enhanced error logging
if (isDevelopment) {
console.error('β [API Response Error]', {
status: error.response?.status,
method: originalRequest?.method?.toUpperCase(),
url: originalRequest ? originalRequest.baseURL + originalRequest.url : 'unknown',
message: error.message,
response: error.response?.data,
headers: error.response?.headers
});
}
// Handle 401 Unauthorized errors
if (error.response?.status === 401) {
if (isDevelopment) {
console.log('π [Auth] 401 error detected, attempting token refresh');
}
// If we haven't retried this request yet
if (!originalRequest._retry) {
originalRequest._retry = true;
try {
// Clear all authentication data
await cookieService.clearAuthTokens();
localStorage.removeItem('token');
if (isDevelopment) {
console.log('π [Auth] Cleared all authentication data');
}
// Redirect to login page
const currentPath = window.location.pathname;
if (currentPath !== '/login' && currentPath !== '/register') {
if (isDevelopment) {
console.log('π [Auth] Redirecting to login page');
}
window.location.href = '/login';
}
} catch (refreshError) {
if (isDevelopment) {
console.error('π [Auth] Error during token refresh:', refreshError);
}
// Even if refresh fails, clear auth data
await cookieService.clearAuthTokens();
localStorage.removeItem('token');
window.location.href = '/login';
return Promise.reject(refreshError);
}
}
}
// Handle network errors
if (!error.response) {
if (isDevelopment) {
console.error('π [Network] No response received:', {
url: originalRequest?.baseURL + originalRequest?.url,
message: error.message
});
}
// You might want to implement offline mode here
// For now, just reject the error
return Promise.reject(error);
}
return Promise.reject(error);
}
);
export default apiClient; |