UNPKG

contentful-sdk-core

Version:
1 lines 5.37 kB
{"version":3,"file":"rate-limit.js","sources":["../../src/rate-limit.ts"],"sourcesContent":["import { noop } from './utils.js'\nimport type { AxiosInstance } from './types.js'\n\nconst delay = (ms: number): Promise<void> =>\n new Promise((resolve) => {\n setTimeout(resolve, ms)\n })\n\nconst defaultWait = (attempts: number): number => {\n return Math.pow(Math.SQRT2, attempts)\n}\n\nexport default function rateLimit(instance: AxiosInstance, maxRetry = 5): void {\n const { responseLogger = noop, requestLogger = noop } = instance.defaults\n\n instance.interceptors.request.use(\n function (config) {\n requestLogger(config)\n return config\n },\n function (error) {\n requestLogger(error)\n return Promise.reject(error)\n },\n )\n\n instance.interceptors.response.use(\n function (response) {\n // we don't need to do anything here\n responseLogger(response)\n return response\n },\n async function (error) {\n const { response } = error\n const { config } = error\n responseLogger(error)\n // Do not retry if it is disabled or no request config exists (not an axios error)\n if (!config || !instance.defaults.retryOnError) {\n return Promise.reject(error)\n }\n\n // Retried already for max attempts\n const doneAttempts = config.attempts || 1\n if (doneAttempts > maxRetry) {\n error.attempts = config.attempts\n return Promise.reject(error)\n }\n\n let retryErrorType = null\n let wait = defaultWait(doneAttempts)\n\n // Errors without response did not receive anything from the server\n if (!response) {\n retryErrorType = 'Connection'\n } else if (response.status >= 500 && response.status < 600) {\n // 5** errors are server related\n retryErrorType = `Server ${response.status}`\n } else if (response.status === 429) {\n // 429 errors are exceeded rate limit exceptions\n retryErrorType = 'Rate limit'\n // all headers are lowercased by axios https://github.com/mzabriskie/axios/issues/413\n if (response.headers && error.response.headers['x-contentful-ratelimit-reset']) {\n wait = response.headers['x-contentful-ratelimit-reset']\n }\n }\n\n if (retryErrorType) {\n // convert to ms and add jitter\n wait = Math.floor(wait * 1000 + Math.random() * 200 + 500)\n instance.defaults.logHandler(\n 'warning',\n `${retryErrorType} error occurred. Waiting for ${wait} ms before retrying...`,\n )\n\n // increase attempts counter\n config.attempts = doneAttempts + 1\n\n /* Somehow between the interceptor and retrying the request the httpAgent/httpsAgent gets transformed from an Agent-like object\n to a regular object, causing failures on retries after rate limits. Removing these properties here fixes the error, but retry\n requests still use the original http/httpsAgent property */\n delete config.httpAgent\n delete config.httpsAgent\n\n return delay(wait).then(() => instance(config))\n }\n return Promise.reject(error)\n },\n )\n}\n"],"names":[],"mappings":"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"}