From bb741ae75b1de445c9c21fab066f6e92c4296f04 Mon Sep 17 00:00:00 2001 From: Phoebe Schmidt Date: Fri, 24 Apr 2020 12:38:39 +0200 Subject: [PATCH] fix(rate-limit): do not store instances and defaults globally --- lib/create-http-client.js | 2 +- lib/rate-limit.js | 11 ++++------- package.json | 2 +- test/unit/rate-limit-test.js | 20 +++++++------------- 4 files changed, 13 insertions(+), 22 deletions(-) diff --git a/lib/create-http-client.js b/lib/create-http-client.js index ce607d7..0d61996 100644 --- a/lib/create-http-client.js +++ b/lib/create-http-client.js @@ -130,6 +130,6 @@ export default function createHttpClient (axios, options) { ...newParams }) } - rateLimit(instance, axiosOptions, config.retryLimit) + rateLimit(instance, config.retryLimit) return instance } diff --git a/lib/rate-limit.js b/lib/rate-limit.js index 14b9ce7..ad000a9 100644 --- a/lib/rate-limit.js +++ b/lib/rate-limit.js @@ -1,12 +1,9 @@ const attempts = {} -const defaultsByInstance = new Map() let networkErrorAttempts = 0 -export default function rateLimit (instance, defaults, maxRetry = 5) { - defaultsByInstance.set(instance, defaults) - const instanceDefaults = defaultsByInstance.get(instance) - const { responseLogger = () => undefined, requestLogger = () => undefined } = instanceDefaults +export default function rateLimit (instance, maxRetry = 5) { + const { responseLogger = () => undefined, requestLogger = () => undefined } = instance.defaults instance.interceptors.request.use(function (config) { requestLogger(config) @@ -22,7 +19,7 @@ export default function rateLimit (instance, defaults, maxRetry = 5) { }, function (error) { let { response, config } = error // Do not retry if it is disabled or no request config exists (not an axios error) - if (!config || !instanceDefaults.retryOnError) { + if (!config || !instance.defaults.retryOnError) { return Promise.reject(error) } @@ -75,7 +72,7 @@ export default function rateLimit (instance, defaults, maxRetry = 5) { if (retryErrorType) { // convert to ms and add jitter wait = Math.floor(wait * 1000 + (Math.random() * 200) + 500) - instanceDefaults.logHandler('warning', `${retryErrorType} error occurred. Waiting for ${wait} ms before retrying...`) + instance.defaults.logHandler('warning', `${retryErrorType} error occurred. Waiting for ${wait} ms before retrying...`) /* Somehow between the interceptor and retrying the request the httpAgent/httpsAgent gets transformed from an Agent-like object to a regular object, causing failures on retries after rate limits. Removing these properties here fixes the error, but retry diff --git a/package.json b/package.json index 69655ea..c3e7aba 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "@babel/node": "^7.2.2", "@babel/preset-env": "^7.2.3", "@babel/register": "^7.0.0", - "axios": "^0.19.0", + "axios": "^0.19.1", "axios-mock-adapter": "^1.15.0", "babel-plugin-rewire": "^1.2.0", "blue-tape": "^1.0.0", diff --git a/test/unit/rate-limit-test.js b/test/unit/rate-limit-test.js index 3b68f15..b52ae79 100644 --- a/test/unit/rate-limit-test.js +++ b/test/unit/rate-limit-test.js @@ -14,27 +14,24 @@ function setup (options = {}) { logHandler: logHandlerStub, retryOnError: true }, options)) - rateLimit(client, { - logHandler: logHandlerStub, - retryOnError: true - }, options.retryLimit) + rateLimit(client, options.retryLimit) return { client } } function setupWithoutErrorRetry () { - const client = axios.create() - rateLimit(client, { + const client = axios.create({ retryOnError: false, logHandler: logHandlerStub }) + rateLimit(client) return { client } } function setupWithOneRetry () { - const client = axios.create() - rateLimit(client, { + const client = axios.create({ retryOnError: true, logHandler: logHandlerStub - }, 1) + }) + rateLimit(client, 1) return { client } } function setupWithNonAxiosError () { @@ -45,10 +42,7 @@ function setupWithNonAxiosError () { client.interceptors.response.use(function (response) { return Promise.reject(new Error('some non-axios error')) }) - rateLimit(client, { - retryOnError: true, - logHandler: logHandlerStub - }) + rateLimit(client) return { client } } function teardown () {