Skip to main content
Glama
client-interceptors.ts3.68 kB
/** * Reusable Axios interceptors for Attio API client * Consolidates duplicate interceptor logic and improves maintainability */ import { AxiosInstance, AxiosResponse, AxiosError, InternalAxiosRequestConfig, } from 'axios'; import { debug, error, OperationType } from '@/utils/logger.js'; export interface InterceptorOptions { prefix?: string; enableDiagnostics?: boolean; enableErrorHandling?: boolean; } /** * Creates a request interceptor that logs outgoing requests with redacted auth */ export function createRequestInterceptor(prefix = '') { return (config: InternalAxiosRequestConfig) => { // Handle null/undefined config gracefully if (!config) { return config; } const redacted = { ...(config.headers || {}) }; if (redacted.Authorization) redacted.Authorization = 'Bearer ***'; const logPrefix = prefix ? `${prefix} ` : ''; debug('attio-client', `${logPrefix}Request sent`, { baseURL: config.baseURL, url: config.url, method: config.method, headers: redacted, }); return config; }; } /** * Creates a response interceptor that logs successful responses */ export function createResponseInterceptor(prefix = '') { return (res: AxiosResponse) => { const logPrefix = prefix ? `${prefix} ` : ''; debug('attio-client', `${logPrefix}Response received`, { status: res.status, url: res.config?.url, topKeys: res?.data && typeof res.data === 'object' ? Object.keys(res.data) : null, rawType: typeof res.data, }); return res; }; } /** * Creates an error interceptor that logs failed requests */ export function createErrorInterceptor(prefix = '') { return (err: AxiosError) => { const r = err?.response; const logPrefix = prefix ? `${prefix} ` : ''; error( 'attio-client', `${logPrefix}HTTP request failed`, err as Error, { url: r?.config?.url, status: r?.status, method: r?.config?.method, serverData: r?.data, requestPayload: r?.config?.data, }, 'http-request', OperationType.API_CALL ); return Promise.reject(err); }; } /** * Adds diagnostic interceptors to an Axios instance * Uses a simple approach without checking for existing interceptors */ export function addDiagnosticInterceptors( client: AxiosInstance, options: InterceptorOptions = {} ): void { const { prefix = '', enableDiagnostics = true } = options; if (!enableDiagnostics) { return; } // Add interceptors (multiple interceptors are allowed and will run in sequence) client.interceptors.request.use(createRequestInterceptor(prefix)); client.interceptors.response.use( createResponseInterceptor(prefix), createErrorInterceptor(prefix) ); } /** * Adds error handling interceptors specifically for Attio API responses */ export function addAttioErrorInterceptors(client: AxiosInstance): void { client.interceptors.response.use( (response: AxiosResponse) => response, (error: AxiosError) => { // This preserves the existing Attio-specific error handling // from the original attio-client.ts implementation return Promise.reject(error); } ); } /** * Configures all standard interceptors for an Attio client */ export function configureStandardInterceptors( client: AxiosInstance, options: InterceptorOptions = {} ): void { const { enableDiagnostics = true, enableErrorHandling = true } = options; if (enableDiagnostics) { addDiagnosticInterceptors(client, options); } if (enableErrorHandling) { addAttioErrorInterceptors(client); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kesslerio/attio-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server