File size: 2,466 Bytes
e026dc9 |
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 |
import axios, { AxiosInstance, AxiosError, InternalAxiosRequestConfig } from "axios";
import { toast } from "react-hot-toast";
// Use relative URL if NEXT_PUBLIC_API_URL is empty (same domain deployment)
// Otherwise use the provided URL or default to localhost
const API_URL = process.env.NEXT_PUBLIC_API_URL === ""
? "" // Empty string means use relative URLs (same domain)
: (process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000");
// Create axios instance
const apiClient: AxiosInstance = axios.create({
baseURL: API_URL,
timeout: 300000, // 5 minutes for long-running operations
headers: {
"Content-Type": "application/json",
},
});
// Request interceptor
apiClient.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
// Add auth token if available
if (typeof window !== "undefined") {
const authStorage = localStorage.getItem("auth-storage");
if (authStorage) {
try {
const auth = JSON.parse(authStorage);
if (auth.state?.token) {
config.headers.Authorization = `Bearer ${auth.state.token}`;
}
} catch (e) {
// Ignore parsing errors
}
}
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
// Response interceptor for error handling
apiClient.interceptors.response.use(
(response) => response,
(error: AxiosError) => {
if (error.response) {
// Server responded with error status
const status = error.response.status;
const message = (error.response.data as any)?.detail || error.message || "An error occurred";
// Handle 401 Unauthorized - redirect to login
if (status === 401) {
if (typeof window !== "undefined" && !window.location.pathname.includes("/login")) {
// Clear auth storage
localStorage.removeItem("auth-storage");
// Redirect to login
window.location.href = "/login";
}
}
// Don't show toast for 404s (handled in components) or 401s (handled above)
if (status !== 404 && status !== 401) {
toast.error(message);
}
} else if (error.request) {
// Request made but no response
toast.error("Network error. Please check your connection.");
} else {
// Something else happened
toast.error("An unexpected error occurred");
}
return Promise.reject(error);
}
);
export default apiClient;
|