@cognigy/rest-api-client
Version:
Cognigy REST-Client
191 lines • 9.41 kB
JavaScript
import { __awaiter } from "tslib";
/* Node Modules */
import Axios from "axios";
/* Custom Modules */
import { ErrorCode, ErrorCollection, NetworkError } from "../shared/errors";
import { HttpStatusCode } from "../shared/helper/HttpStatusCode";
import { OAuth2Errors } from "../authentication/OAuth2/IOAuth2ErrorResponse";
import { isRetryAllowed } from "./isRetryAllowed";
import { isRetryableStatus } from "./isRetryableStatus";
import { exponentialDelay } from "./exponentialDelay";
import { retryAfterDelay } from "./retryAfterDelay";
export class AxiosAdapter {
constructor(config) {
this.config = config;
}
setConfig(config) {
this.config = config;
}
request(request, client) {
var _a, _b, _c, _d;
return __awaiter(this, void 0, void 0, function* () {
const { maxRetries = (_b = (_a = this.config.maxRetries) !== null && _a !== void 0 ? _a : client.config.maxRetries) !== null && _b !== void 0 ? _b : 3, retryCondition = AxiosAdapter.isNetworkOrIdempotentRequestError, retryDelay = exponentialDelay, shouldResetTimeout = false } = request;
if (request.withAuthentication) {
const authenticationHeaders = yield ((_c = client.authenticationHandler) === null || _c === void 0 ? void 0 : _c.getAuthenticationHeaders());
request.headers = Object.assign(Object.assign({}, request.headers), authenticationHeaders);
}
const axiosRequest = yield this.convertRequest(request, client);
request.lastRequestTime = Date.now();
request.retryCount = request.retryCount || 0;
if (request.retryCount === maxRetries) {
axiosRequest.validateStatus = null;
}
let axiosResponse;
try {
axiosResponse = yield Axios(axiosRequest);
}
catch (error) {
if (isAxiosError(error)) {
const shouldRetry = retryCondition(error) && request.retryCount < maxRetries;
if (shouldRetry) {
request.retryCount += 1;
const delay = retryAfterDelay((_d = error.response) === null || _d === void 0 ? void 0 : _d.headers, request.lastRequestTime) || retryDelay(request.retryCount, error);
if (!shouldResetTimeout &&
request.timeout &&
request.lastRequestTime) {
const lastRequestDuration = Date.now() - request.lastRequestTime;
request.timeout = Math.max(request.timeout - lastRequestDuration - delay, 1);
}
const requestPromise = new Promise((resolve) => setTimeout(() => resolve(this.request(request, client)), delay));
const response = yield requestPromise;
return response;
}
}
this.handleError(error);
}
if (isAxiosError(axiosResponse) || axiosResponse.status >= 400) {
this.handleError(axiosResponse);
}
const response = yield this.convertResponse(axiosResponse);
return response;
});
}
get(request, client) {
return __awaiter(this, void 0, void 0, function* () {
return this.request(Object.assign(Object.assign({}, request), { method: "GET" }), client);
});
}
post(request, client) {
return __awaiter(this, void 0, void 0, function* () {
return this.request(Object.assign(Object.assign({}, request), { method: "POST" }), client);
});
}
patch(request, client) {
return __awaiter(this, void 0, void 0, function* () {
return this.request(Object.assign(Object.assign({}, request), { method: "PATCH" }), client);
});
}
put(request, client) {
return __awaiter(this, void 0, void 0, function* () {
return this.request(Object.assign(Object.assign({}, request), { method: "PUT" }), client);
});
}
head(request, client) {
return __awaiter(this, void 0, void 0, function* () {
return this.request(Object.assign(Object.assign({}, request), { method: "HEAD" }), client);
});
}
convertRequest(request, client) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
const baseUrl = (_a = request.baseUrl) !== null && _a !== void 0 ? _a : this.config.baseUrl;
const axiosRequest = {
data: request.data,
headers: request.headers,
method: request.method || "GET",
url: `${baseUrl}${request.url}`,
validateStatus: (status) => !isRetryableStatus(status)
};
if (typeof request.onProgress === "function") {
axiosRequest.onDownloadProgress = (progressEvent) => {
const { loaded, total } = progressEvent;
return request.onProgress({ loaded, total });
};
axiosRequest.onUploadProgress = (progressEvent) => {
const { loaded, total } = progressEvent;
return request.onProgress({ loaded, total });
};
}
return axiosRequest;
});
}
handleError(axiosResponse) {
var _a, _b, _c, _d;
if (isAxiosError(axiosResponse)) {
if (AxiosAdapter.isNetworkError(axiosResponse)) {
throw new NetworkError("Request failed. Please check your Network Connection or Firewall Settings.", null, axiosResponse, axiosResponse);
}
else {
const data = ((_a = axiosResponse.response) === null || _a === void 0 ? void 0 : _a.data) || {
code: 500,
detail: "An unexpected error occurred. Please try again later.",
details: {},
traceId: "aixos-error-trace-id"
};
const errorClass = ErrorCollection[data.code] ||
ErrorCollection[ErrorCode.INTERNAL_SERVER_ERROR];
throw new errorClass(data.detail, { traceId: data.traceId }, undefined, data.details);
}
}
if (isAxiosResponse(axiosResponse)) {
const errorClass = ErrorCollection[(_b = axiosResponse.data) === null || _b === void 0 ? void 0 : _b.code] ||
ErrorCollection[axiosResponse.status] ||
ErrorCollection[ErrorCode.INTERNAL_SERVER_ERROR];
if ((axiosResponse.status === HttpStatusCode.UNAUTHORIZED ||
errorClass === ErrorCollection[ErrorCode.UNAUTHORIZED_ERROR] ||
OAuth2Errors.includes((_c = axiosResponse.data) === null || _c === void 0 ? void 0 : _c.error)) &&
typeof this.config.onUnauthorized === "function") {
this.config.onUnauthorized();
}
if (OAuth2Errors.includes((_d = axiosResponse.data) === null || _d === void 0 ? void 0 : _d.error)) {
throw new errorClass(axiosResponse.data.detail, { traceId: axiosResponse.data.traceId }, undefined, axiosResponse.data);
}
throw new errorClass(axiosResponse.data.detail, { traceId: axiosResponse.data.traceId }, undefined, axiosResponse.data.details);
}
}
convertResponse(axiosResponse) {
return __awaiter(this, void 0, void 0, function* () {
const response = {
data: axiosResponse.data,
headers: axiosResponse.headers,
status: axiosResponse.status,
statusText: axiosResponse.statusText
};
return response;
});
}
static isNetworkError(error) {
return (
// https://github.com/softonic/axios-retry/issues/138
(error.isAxiosError && error.message === "Network Error") ||
(!error.response &&
Boolean(error.code) && // Prevents retrying cancelled requests
error.code !== "ECONNABORTED" && // Prevents retrying timed out requests
isRetryAllowed(error.code)) // Prevents retrying unsafe errors
);
}
static isRetryableError(error) {
return (error.code !== "ECONNABORTED" &&
(!error.response || isRetryableStatus(error.response.status)));
}
static isIdempotentRequestError(error) {
if (!error.config) {
// Cannot determine if the request can be retried
return false;
}
return (AxiosAdapter.isRetryableError(error) &&
["get", "head", "options", "put", "delete"].indexOf(error.config.method.toLowerCase()) !== -1);
}
static isNetworkOrIdempotentRequestError(error) {
return (AxiosAdapter.isNetworkError(error) ||
AxiosAdapter.isIdempotentRequestError(error));
}
}
export function isAxiosError(error) {
return (error === null || error === void 0 ? void 0 : error.isAxiosError) === true;
}
export function isAxiosResponse(error) {
return ((error === null || error === void 0 ? void 0 : error.isAxiosError) === undefined ||
(error === null || error === void 0 ? void 0 : error.isAxiosError) === false);
}
//# sourceMappingURL=AxiosAdapter.js.map