diff --git a/src/metrics.ts b/src/metrics.ts index e57f64d3..b093ac6e 100644 --- a/src/metrics.ts +++ b/src/metrics.ts @@ -225,9 +225,10 @@ export default class Metrics extends EventEmitter { httpOptions: this.httpOptions, }); if (!res.ok) { - if (res.status === 404 || res.status === 403 || res.status == 401) { + if (res.status === 403 || res.status == 401) { this.configurationError(url, res.status); } else if ( + res.status === 404 || res.status === 429 || res.status === 500 || res.status === 502 || diff --git a/src/repository/index.ts b/src/repository/index.ts index 588f796f..7c54b7af 100644 --- a/src/repository/index.ts +++ b/src/repository/index.ts @@ -270,15 +270,7 @@ Message: ${err.message}`, // and returns 0 as the next fetch interval (stop polling) private configurationError(url: string, statusCode: number): number { this.failures += 1; - if (statusCode === 404) { - this.emit( - UnleashEvents.Error, - new Error( - // eslint-disable-next-line max-len - `${url} responded NOT_FOUND (404) which means your API url most likely needs correction. Stopping refresh of toggles`, - ), - ); - } else if (statusCode === 401 || statusCode === 403) { + if (statusCode === 401 || statusCode === 403) { this.emit( UnleashEvents.Error, new Error( @@ -294,7 +286,7 @@ Message: ${err.message}`, // and return the new interval. private recoverableError(url: string, statusCode: number): number { let nextFetch = this.backoff(); - if (statusCode === 429) { + if (statusCode === 404 || statusCode === 429) { this.emit( UnleashEvents.Warn, // eslint-disable-next-line max-len @@ -312,9 +304,10 @@ Message: ${err.message}`, } private handleErrorCases(url: string, statusCode: number): number { - if (statusCode === 401 || statusCode === 403 || statusCode === 404) { + if (statusCode === 401 || statusCode === 403) { return this.configurationError(url, statusCode); } else if ( + statusCode === 404 || statusCode === 429 || statusCode === 500 || statusCode === 502 || diff --git a/src/test/metrics.test.ts b/src/test/metrics.test.ts index aae40cbf..24dea0c1 100644 --- a/src/test/metrics.test.ts +++ b/src/test/metrics.test.ts @@ -252,29 +252,28 @@ test('registerInstance should warn when non 200 statusCode', async (t) => { metrics.start(); }); -test('sendMetrics should stop/disable metrics if endpoint returns 404', (t) => - new Promise((resolve) => { - const url = getUrl(); - const metEP = nockMetrics(url, 404); - // @ts-expect-error - const metrics = new Metrics({ - metricsInterval: 50, - url, - }); - - metrics.on('warn', () => { - metrics.stop(); - t.true(metEP.isDone()); - // @ts-expect-error - t.true(metrics.disabled); - resolve(); - }); - metrics.start(); - - metrics.count('x-y-z', true); - - metrics.sendMetrics(); - })); +test('sendMetrics should backoff on 404', async (t) => { + const url = getUrl(); + nockMetrics(url, 404).persist(); + const metrics = new Metrics({ + appName: '404-tester', + instanceId: '404-instance', + metricsInterval: 10, + strategies: [], + url, + }); + metrics.count('x-y-z', true); + await metrics.sendMetrics(); + // @ts-expect-error actually a private field, but we access it for tests + t.false(metrics.disabled); + t.is(metrics.getFailures(), 1); + t.is(metrics.getInterval(), 20); + await metrics.sendMetrics(); + // @ts-expect-error actually a private field, but we access it for tests + t.false(metrics.disabled); + t.is(metrics.getFailures(), 2); + t.is(metrics.getInterval(), 30); +}); test('sendMetrics should emit warn on non 200 statusCode', (t) => new Promise((resolve) => {