From 03302a47ccd3f244674a9ade8c530b956475f3b7 Mon Sep 17 00:00:00 2001 From: Rhys Arkins <rhys@arkins.net> Date: Fri, 9 Feb 2018 10:15:53 +0100 Subject: [PATCH] fix: retry npmjs when receiving 5xx errors --- lib/manager/npm/registry.js | 12 +++++++++--- test/manager/npm/registry.spec.js | 15 +++++++++++++-- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/lib/manager/npm/registry.js b/lib/manager/npm/registry.js index 8f110e3ab2..b150c4a933 100644 --- a/lib/manager/npm/registry.js +++ b/lib/manager/npm/registry.js @@ -3,6 +3,7 @@ const got = require('got'); const url = require('url'); const ini = require('ini'); +const delay = require('delay'); const getRegistryUrl = require('registry-auth-token/registry-url'); const registryAuthToken = require('registry-auth-token'); const parse = require('github-url-from-git'); @@ -64,7 +65,7 @@ function envReplace(value, env = process.env) { }); } -async function getDependency(name) { +async function getDependency(name, retries = 5) { logger.trace(`getDependency(${name})`); if (memcache[name]) { logger.debug('Returning cached result'); @@ -148,8 +149,13 @@ async function getDependency(name) { throw new Error('registry-failure'); } if (err.statusCode >= 500 && err.statusCode < 600) { - logger.warn({ err }, 'npm registry failure: internal error'); - throw new Error('registry-failure'); + if (retries <= 0) { + logger.warn({ err }, 'npm registry failure: internal error, retries=0'); + throw new Error('registry-failure'); + } + logger.info({ err }, 'npm registry failure: internal error, retrying'); + await delay(5000 / retries); + return getDependency(name, retries - 1); } logger.warn({ err, name }, 'npm registry failures: Unknown error'); throw new Error('registry-failure'); diff --git a/test/manager/npm/registry.spec.js b/test/manager/npm/registry.spec.js index 391cd0ca0f..88f05a2f70 100644 --- a/test/manager/npm/registry.spec.js +++ b/test/manager/npm/registry.spec.js @@ -3,6 +3,7 @@ const registryAuthToken = require('registry-auth-token'); const nock = require('nock'); jest.mock('registry-auth-token'); +jest.mock('delay'); const npmResponse = { versions: { @@ -98,11 +99,21 @@ describe('api/npm', () => { .reply(503); let e; try { - await npm.getDependency('foobar'); + await npm.getDependency('foobar', 0); } catch (err) { e = err; } - expect(e).toBeDefined(); + expect(e.message).toBe('registry-failure'); + }); + it('should retry when 5xx', async () => { + nock('https://registry.npmjs.org') + .get('/foobar') + .reply(503); + nock('https://registry.npmjs.org') + .get('/foobar') + .reply(200); + const res = await npm.getDependency('foobar'); + expect(res).toBe(null); }); it('should throw error for others', async () => { nock('https://registry.npmjs.org') -- GitLab