created at 2025/06/14 13:54:16
updated at 2025/06/14 13:54:47
TypeScript
import axios, { AxiosError, AxiosInstance, AxiosRequestConfig } from "axios";
interface RequestConfig extends AxiosRequestConfig {
retry?: number;
retryDelay?: number;
}
interface ErrorResponse {
status: number;
message: string;
data?: unknown;
}
class HttpClient {
private instance: AxiosInstance;
private defaultRetryTimes = 3;
private defaultRetryDelay = 1000;
constructor(config: AxiosRequestConfig = {}) {
this.instance = axios.create({
timeout: 10000,
...config,
});
this.setupInterceptors();
}
private setupInterceptors() {
this.instance.interceptors.request.use(
(config) => {
config.headers["Content-Type"] = "application/json";
return config;
},
(error) => {
return Promise.reject(this.handleError(error));
}
);
// Response interceptor
this.instance.interceptors.response.use(
(response) => response,
async (error) => {
const config = error.config as RequestConfig;
// Initialize retry count
config.retry = config.retry ?? this.defaultRetryTimes;
config.retryDelay = config.retryDelay ?? this.defaultRetryDelay;
if (config.retry > 0) {
config.retry--;
// Wait for specified delay
await new Promise((resolve) =>
setTimeout(resolve, config.retryDelay)
);
// Retry the request
return this.instance(config);
}
return Promise.reject(this.handleError(error));
}
);
}
private handleError(error: AxiosError): ErrorResponse {
if (error.response) {
// Server responded with error status
return {
status: error.response.status,
message: error.response.statusText,
data: error.response.data,
};
} else if (error.request) {
// Request was made but no response received
return {
status: 0,
message: "No response received from server",
data: error.request,
};
} else {
// Request setup error
return {
status: -1,
message: error.message || "Request failed",
data: error,
};
}
}
async get<T = unknown>(url: string, config?: RequestConfig): Promise<T> {
try {
const response = await this.instance.get<T>(url, config);
return response.data;
} catch (error) {
throw error;
}
}
async post<T = unknown>(
url: string,
data?: unknown,
config?: RequestConfig
): Promise<T> {
try {
const response = await this.instance.post<T>(url, data, config);
return response.data;
} catch (error) {
throw error;
}
}
async put<T = unknown>(
url: string,
data?: unknown,
config?: RequestConfig
): Promise<T> {
try {
const response = await this.instance.put<T>(url, data, config);
return response.data;
} catch (error) {
throw error;
}
}
async delete<T = unknown>(url: string, config?: RequestConfig): Promise<T> {
try {
const response = await this.instance.delete<T>(url, config);
return response.data;
} catch (error) {
throw error;
}
}
}
export const http = new HttpClient();
export default HttpClient;