UNPKG

guardz-axios

Version:

Type-safe HTTP client built on top of Axios with runtime validation using guardz. Part of the guardz ecosystem for comprehensive TypeScript type safety.

143 lines 6.23 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.executeRequest = executeRequest; const axios_1 = __importDefault(require("axios")); const guardz_1 = require("guardz"); const axios_error_guards_1 = require("../../guards/axios-error-guards"); const axios_response_guards_1 = require("../../guards/axios-response-guards"); const status_types_1 = require("../../types/status-types"); const isRetryableError_1 = require("./isRetryableError"); /** * Core execution function with retry logic and comprehensive error handling */ async function executeRequest(axiosConfig, safeConfig) { const { guard, tolerance = false, identifier, onTypeMismatch, axiosInstance = axios_1.default, validateResponse = true, retry, timeout, } = safeConfig; const finalConfig = { ...axiosConfig, timeout: timeout || axiosConfig.timeout, }; const url = finalConfig.url || ""; const method = (finalConfig.method || "GET").toUpperCase(); let attempt = 0; const maxAttempts = retry?.attempts || 1; while (attempt < maxAttempts) { attempt++; try { // Add delay for retries if (attempt > 1 && retry) { const delay = retry.backoff === "exponential" ? retry.delay * Math.pow(2, attempt - 2) : retry.delay * (attempt - 1); await new Promise((resolve) => setTimeout(resolve, delay)); } const response = await axiosInstance.request(finalConfig); // Validate response structure if requested if (validateResponse && !(0, axios_response_guards_1.isAxiosResponse)(response)) { const errorMsg = "Invalid response structure"; const context = { type: "validation", url, method, originalError: response, }; onTypeMismatch?.(errorMsg, context); if (!tolerance) { return { status: status_types_1.Status.ERROR, code: 500, message: errorMsg }; } } // Validate response data let validatedData; let isValidated = true; let validationErrors = []; if (tolerance) { // Use tolerance mode const errorMessages = []; const toleranceConfig = { identifier: identifier || url, callbackOnError: (errorMessage) => { errorMessages.push(errorMessage); onTypeMismatch?.(errorMessage, { type: "validation", url, method, originalError: response.data, }); }, }; validatedData = (0, guardz_1.guardWithTolerance)(response.data, guard, toleranceConfig); if (errorMessages.length > 0) { isValidated = false; validationErrors = errorMessages; } } else { // Strict mode const errorMessages = []; const strictConfig = { identifier: identifier || url, callbackOnError: (errorMessage) => { errorMessages.push(errorMessage); }, }; if (guard(response.data, strictConfig)) { validatedData = response.data; } else { const errorMsg = errorMessages.length > 0 ? `Response data validation failed: ${errorMessages.join(", ")}` : "Response data validation failed"; const context = { type: "validation", url, method, originalError: response.data, }; onTypeMismatch?.(errorMsg, context); return { status: status_types_1.Status.ERROR, code: 500, message: errorMsg }; } } return { status: status_types_1.Status.SUCCESS, data: validatedData }; } catch (error) { // Check if we should retry const shouldRetry = attempt < maxAttempts && Boolean(retry?.retryOn ? retry.retryOn(error) : (0, isRetryableError_1.isRetryableError)(error)); if (!shouldRetry) { // Handle final error let errorType = "unknown"; let statusCode; if ((0, axios_error_guards_1.isAxiosError)(error)) { const categorized = (0, axios_error_guards_1.categorizeAxiosError)(error); errorType = categorized.category === "network" ? "network" : categorized.category === "timeout" ? "timeout" : "unknown"; statusCode = categorized.statusCode; } const context = { type: errorType, url, method, statusCode, originalError: error, }; const errorMsg = error instanceof Error ? error.message : "Unknown error"; onTypeMismatch?.(errorMsg, context); return { status: status_types_1.Status.ERROR, code: 500, message: errorMsg }; } // If shouldRetry is true, continue to next iteration } } // This should never be reached, but TypeScript requires it return { status: status_types_1.Status.ERROR, code: 500, message: "Maximum retry attempts exceeded", }; } //# sourceMappingURL=executeRequest.js.map