File size: 1,747 Bytes
6d643ca
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import axios, {
  AxiosError,
  AxiosResponse,
  InternalAxiosRequestConfig,
} from 'axios';

import { API_CONFIG } from '@/lib/config';
import { ApiError, NetworkError } from '@/lib/errors';
import { HTTP_STATUS, STORAGE_KEYS } from '@/utils/constants';

// Create axios instance
export const apiClient = axios.create({
  baseURL: API_CONFIG.BASE_URL,
  headers: {
    'Content-Type': 'application/json',
  },
  timeout: API_CONFIG.TIMEOUT,
});

// Request interceptor
apiClient.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    // Add auth token if available
    const token = localStorage.getItem(STORAGE_KEYS.AUTH_TOKEN);
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error: unknown) =>
    Promise.reject(error instanceof Error ? error : new Error(String(error)))
);

// Response interceptor
apiClient.interceptors.response.use(
  (response: AxiosResponse) => response,
  (error: AxiosError) => {
    const statusCode = error.response?.status;
    const responseData = error.response?.data as Record<string, unknown>;
    const message =
      typeof responseData?.message === 'string'
        ? responseData.message
        : error.message;
    const code =
      typeof responseData?.code === 'string' ? responseData.code : undefined;

    // Handle specific error types
    if (!error.response) {
      // Network error
      throw new NetworkError('Network connection failed', 0);
    }

    if (statusCode && statusCode >= HTTP_STATUS.BAD_REQUEST) {
      throw new ApiError(
        message,
        statusCode,
        code,
        responseData?.details as Record<string, unknown> | undefined
      );
    }

    return Promise.reject(error);
  }
);