From a12ae7aaa5291835b23ed3da5c84fd5952f08ea0 Mon Sep 17 00:00:00 2001 From: WebStreamr <210764791+webstreamr@users.noreply.github.com> Date: Wed, 13 Aug 2025 10:49:36 +0000 Subject: [PATCH] chore(fetcher): retry 5xx errors up to 3 times --- src/utils/Fetcher.test.ts | 4 ++-- src/utils/Fetcher.ts | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/utils/Fetcher.test.ts b/src/utils/Fetcher.test.ts index 80c7a77..3270809 100644 --- a/src/utils/Fetcher.test.ts +++ b/src/utils/Fetcher.test.ts @@ -208,9 +208,9 @@ describe('fetch', () => { } }); - test('passes through other error as HttpError', async () => { + test('passes through other error as HttpError after retrying 3 times', async () => { const mockPool = mockAgent.get('https://some-error-url.test'); - mockPool.intercept({ path: '/' }).reply(500, undefined, { headers: { 'x-foo': 'bar' } }); + mockPool.intercept({ path: '/' }).reply(500, undefined, { headers: { 'x-foo': 'bar' } }).times(4); try { await fetcher.text(ctx, new URL('https://some-error-url.test/')); diff --git a/src/utils/Fetcher.ts b/src/utils/Fetcher.ts index f5abaa7..c13ff4b 100644 --- a/src/utils/Fetcher.ts +++ b/src/utils/Fetcher.ts @@ -248,7 +248,7 @@ export class Fetcher { return this.handleHttpCacheItem(ctx, httpCacheItem, url, init); }; - protected async fetchWithTimeout(ctx: Context, url: URL, init?: CustomRequestInit): Promise { + protected async fetchWithTimeout(ctx: Context, url: URL, init?: CustomRequestInit, tryCount = 0): Promise { this.logger.info(`Fetch ${init?.method ?? 'GET'} ${url}`, ctx); if (this.rateLimitedCache.has(url.host)) { @@ -279,6 +279,12 @@ export class Fetcher { await this.decreaseTimeoutsCount(url); + if (response.status >= 500 && tryCount < 3) { + await new Promise(sleep => setTimeout(sleep, 333)); + + return await this.fetchWithTimeout(ctx, url, init, ++tryCount); + } + return response; };