2024-04-09 05:14:49 +00:00
|
|
|
import log from "@/next/log";
|
2024-05-24 12:50:40 +00:00
|
|
|
import axios, { type AxiosRequestConfig, type AxiosResponse } from "axios";
|
2024-02-24 08:18:57 +00:00
|
|
|
import { ApiError, CustomError, isApiErrorResponse } from "../error";
|
2023-11-02 03:36:31 +00:00
|
|
|
|
|
|
|
interface IHTTPHeaders {
|
|
|
|
[headerKey: string]: any;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface IQueryPrams {
|
|
|
|
[paramName: string]: any;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Service to manage all HTTP calls.
|
|
|
|
*/
|
|
|
|
class HTTPService {
|
|
|
|
constructor() {
|
|
|
|
axios.interceptors.response.use(
|
|
|
|
(response) => Promise.resolve(response),
|
|
|
|
(error) => {
|
2023-11-02 15:22:31 +00:00
|
|
|
const config = error.config as AxiosRequestConfig;
|
2023-11-02 03:36:31 +00:00
|
|
|
if (error.response) {
|
|
|
|
const response = error.response as AxiosResponse;
|
|
|
|
let apiError: ApiError;
|
|
|
|
// The request was made and the server responded with a status code
|
|
|
|
// that falls out of the range of 2xx
|
|
|
|
if (isApiErrorResponse(response.data)) {
|
|
|
|
const responseData = response.data;
|
2024-04-09 05:14:49 +00:00
|
|
|
log.error(
|
|
|
|
`HTTP Service Error - ${JSON.stringify({
|
2024-05-20 06:13:10 +00:00
|
|
|
url: config?.url,
|
|
|
|
method: config?.method,
|
2024-04-09 05:14:49 +00:00
|
|
|
xRequestId: response.headers["x-request-id"],
|
|
|
|
httpStatus: response.status,
|
|
|
|
errMessage: responseData.message,
|
|
|
|
errCode: responseData.code,
|
|
|
|
})}`,
|
|
|
|
error,
|
|
|
|
);
|
2023-11-02 03:36:31 +00:00
|
|
|
apiError = new ApiError(
|
|
|
|
responseData.message,
|
|
|
|
responseData.code,
|
2024-02-24 08:18:57 +00:00
|
|
|
response.status,
|
2023-11-02 03:36:31 +00:00
|
|
|
);
|
|
|
|
} else {
|
|
|
|
if (response.status >= 400 && response.status < 500) {
|
|
|
|
apiError = new ApiError(
|
|
|
|
CustomError.CLIENT_ERROR,
|
2024-02-24 08:18:57 +00:00
|
|
|
"",
|
|
|
|
response.status,
|
2023-11-02 03:36:31 +00:00
|
|
|
);
|
|
|
|
} else {
|
|
|
|
apiError = new ApiError(
|
|
|
|
CustomError.ServerError,
|
2024-02-24 08:18:57 +00:00
|
|
|
"",
|
|
|
|
response.status,
|
2023-11-02 03:36:31 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2024-04-09 05:14:49 +00:00
|
|
|
log.error(
|
|
|
|
`HTTP Service Error - ${JSON.stringify({
|
|
|
|
url: config.url,
|
|
|
|
method: config.method,
|
|
|
|
cfRay: response.headers["cf-ray"],
|
|
|
|
xRequestId: response.headers["x-request-id"],
|
|
|
|
httpStatus: response.status,
|
|
|
|
})}`,
|
|
|
|
apiError,
|
|
|
|
);
|
2023-11-02 03:36:31 +00:00
|
|
|
throw apiError;
|
|
|
|
} else if (error.request) {
|
|
|
|
// The request was made but no response was received
|
|
|
|
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
|
|
|
|
// http.ClientRequest in node.js
|
2024-04-09 05:14:49 +00:00
|
|
|
log.info(
|
|
|
|
`request failed - no response (${config.method} ${config.url}`,
|
2023-11-02 15:24:20 +00:00
|
|
|
);
|
2023-11-02 03:36:31 +00:00
|
|
|
return Promise.reject(error);
|
|
|
|
} else {
|
2024-04-09 05:14:49 +00:00
|
|
|
// Something happened in setting up the request that
|
|
|
|
// triggered an Error
|
|
|
|
log.info(
|
|
|
|
`request failed - axios error (${config.method} ${config.url}`,
|
2023-11-02 15:24:20 +00:00
|
|
|
);
|
2023-11-02 03:36:31 +00:00
|
|
|
return Promise.reject(error);
|
|
|
|
}
|
2024-02-24 08:18:57 +00:00
|
|
|
},
|
2023-11-02 03:36:31 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* header object to be append to all api calls.
|
|
|
|
*/
|
|
|
|
private headers: IHTTPHeaders = {
|
2024-02-24 08:18:57 +00:00
|
|
|
"content-type": "application/json",
|
2023-11-02 03:36:31 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the headers to the given object.
|
|
|
|
*/
|
|
|
|
public setHeaders(headers: IHTTPHeaders) {
|
|
|
|
this.headers = {
|
|
|
|
...this.headers,
|
|
|
|
...headers,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds a header to list of headers.
|
|
|
|
*/
|
|
|
|
public appendHeader(key: string, value: string) {
|
|
|
|
this.headers = {
|
|
|
|
...this.headers,
|
|
|
|
[key]: value,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Removes the given header.
|
|
|
|
*/
|
|
|
|
public removeHeader(key: string) {
|
|
|
|
this.headers[key] = undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns axios interceptors.
|
|
|
|
*/
|
|
|
|
public getInterceptors() {
|
|
|
|
return axios.interceptors;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generic HTTP request.
|
|
|
|
* This is done so that developer can use any functionality
|
|
|
|
* provided by axios. Here, only the set headers are spread
|
|
|
|
* over what was sent in config.
|
|
|
|
*/
|
|
|
|
public async request(config: AxiosRequestConfig, customConfig?: any) {
|
|
|
|
config.headers = {
|
|
|
|
...this.headers,
|
|
|
|
...config.headers,
|
|
|
|
};
|
|
|
|
if (customConfig?.cancel) {
|
|
|
|
config.cancelToken = new axios.CancelToken(
|
2024-02-24 08:18:57 +00:00
|
|
|
(c) => (customConfig.cancel.exec = c),
|
2023-11-02 03:36:31 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
return await axios({ ...config, ...customConfig });
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get request.
|
|
|
|
*/
|
|
|
|
public get(
|
|
|
|
url: string,
|
|
|
|
params?: IQueryPrams,
|
|
|
|
headers?: IHTTPHeaders,
|
2024-02-24 08:18:57 +00:00
|
|
|
customConfig?: any,
|
2023-11-02 03:36:31 +00:00
|
|
|
) {
|
|
|
|
return this.request(
|
|
|
|
{
|
|
|
|
headers,
|
2024-02-24 08:18:57 +00:00
|
|
|
method: "GET",
|
2023-11-02 03:36:31 +00:00
|
|
|
params,
|
|
|
|
url,
|
|
|
|
},
|
2024-02-24 08:18:57 +00:00
|
|
|
customConfig,
|
2023-11-02 03:36:31 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Post request
|
|
|
|
*/
|
|
|
|
public post(
|
|
|
|
url: string,
|
|
|
|
data?: any,
|
|
|
|
params?: IQueryPrams,
|
|
|
|
headers?: IHTTPHeaders,
|
2024-02-24 08:18:57 +00:00
|
|
|
customConfig?: any,
|
2023-11-02 03:36:31 +00:00
|
|
|
) {
|
|
|
|
return this.request(
|
|
|
|
{
|
|
|
|
data,
|
|
|
|
headers,
|
2024-02-24 08:18:57 +00:00
|
|
|
method: "POST",
|
2023-11-02 03:36:31 +00:00
|
|
|
params,
|
|
|
|
url,
|
|
|
|
},
|
2024-02-24 08:18:57 +00:00
|
|
|
customConfig,
|
2023-12-24 22:01:03 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Patch request
|
|
|
|
*/
|
|
|
|
public patch(
|
|
|
|
url: string,
|
|
|
|
data?: any,
|
|
|
|
params?: IQueryPrams,
|
|
|
|
headers?: IHTTPHeaders,
|
2024-02-24 08:18:57 +00:00
|
|
|
customConfig?: any,
|
2023-12-24 22:01:03 +00:00
|
|
|
) {
|
|
|
|
return this.request(
|
|
|
|
{
|
|
|
|
data,
|
|
|
|
headers,
|
2024-02-24 08:18:57 +00:00
|
|
|
method: "PATCH",
|
2023-12-24 22:01:03 +00:00
|
|
|
params,
|
|
|
|
url,
|
|
|
|
},
|
2024-02-24 08:18:57 +00:00
|
|
|
customConfig,
|
2023-11-02 03:36:31 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Put request
|
|
|
|
*/
|
|
|
|
public put(
|
|
|
|
url: string,
|
|
|
|
data: any,
|
|
|
|
params?: IQueryPrams,
|
|
|
|
headers?: IHTTPHeaders,
|
2024-02-24 08:18:57 +00:00
|
|
|
customConfig?: any,
|
2023-11-02 03:36:31 +00:00
|
|
|
) {
|
|
|
|
return this.request(
|
|
|
|
{
|
|
|
|
data,
|
|
|
|
headers,
|
2024-02-24 08:18:57 +00:00
|
|
|
method: "PUT",
|
2023-11-02 03:36:31 +00:00
|
|
|
params,
|
|
|
|
url,
|
|
|
|
},
|
2024-02-24 08:18:57 +00:00
|
|
|
customConfig,
|
2023-11-02 03:36:31 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Delete request
|
|
|
|
*/
|
|
|
|
public delete(
|
|
|
|
url: string,
|
|
|
|
data: any,
|
|
|
|
params?: IQueryPrams,
|
|
|
|
headers?: IHTTPHeaders,
|
2024-02-24 08:18:57 +00:00
|
|
|
customConfig?: any,
|
2023-11-02 03:36:31 +00:00
|
|
|
) {
|
|
|
|
return this.request(
|
|
|
|
{
|
|
|
|
data,
|
|
|
|
headers,
|
2024-02-24 08:18:57 +00:00
|
|
|
method: "DELETE",
|
2023-11-02 03:36:31 +00:00
|
|
|
params,
|
|
|
|
url,
|
|
|
|
},
|
2024-02-24 08:18:57 +00:00
|
|
|
customConfig,
|
2023-11-02 03:36:31 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Creates a Singleton Service.
|
|
|
|
// This will help me maintain common headers / functionality
|
|
|
|
// at a central place.
|
|
|
|
export default new HTTPService();
|