UNPKG

@vepler/http-client

Version:

A flexible and extensible API service library for making HTTP requests with built-in authentication support for bearer tokens and API keys.

78 lines (67 loc) 3.14 kB
import logger from '@vepler/logger'; import { AxiosError } from 'axios'; import { HttpError, createErrorFromResponse, TimeoutError, NetworkError, ClientError } from '../errors/http-error'; import { parseAxiosError } from '../errors/error-utils'; /** * Response error interceptor that converts Axios errors to typed HttpError instances * and logs them with proper context and sensitive data masking */ export default (error: AxiosError): Promise<never> => { // Create typed, detailed error based on the response let httpError: HttpError; try { if (error.response) { // Server responded with an error status (4xx, 5xx) httpError = createErrorFromResponse(error.response); // Log error with contextual information but mask sensitive data const errorObj = new Error(`[HTTP ${httpError.status}] ${httpError.name}: ${httpError.message}`); logger.error(errorObj, 'HTTP Response Error', { status: httpError.status, endpoint: httpError.endpoint, errorDetails: parseAxiosError(error) }); } else if (error.code === 'ECONNABORTED') { // Timeout error const { url, method } = error.config || {}; httpError = new TimeoutError( `Request timeout after ${error.config?.timeout}ms - ${method?.toUpperCase()} ${url}`, error.request, url, method?.toUpperCase() ); const timeoutError = new Error(`[TIMEOUT] ${httpError.message}`); logger.error(timeoutError, 'Request Timeout Error', { timeout: error.config?.timeout, url, method }); } else if (error.request) { // Request was made but no response received (network error) const { url, method } = error.config || {}; httpError = new NetworkError( `Network error - ${method?.toUpperCase()} ${url}`, error.request, url, method?.toUpperCase() ); const networkError = new Error(`[NETWORK] ${httpError.message}`); logger.error(networkError, 'Network Error', { url, method }); } else { // Error in setting up the request httpError = new ClientError(error.message || 'Request setup error'); const clientError = new Error(`[CLIENT] ${httpError.message}`); logger.error(clientError, 'Client Error'); } } catch (loggingError) { // Fallback in case error parsing/logging fails const processingError = new Error('Error while processing HTTP error'); logger.error(processingError, 'Error Processing', { loggingError }); // Still create a basic error httpError = new HttpError(error.message || 'Unknown HTTP error'); } // Return a rejected promise with our typed error return Promise.reject(httpError); };