From 95465b4b8dbb95afb91f57b07e2457b3bb8495e2 Mon Sep 17 00:00:00 2001 From: Petromir Petrov Date: Fri, 13 Dec 2024 17:42:53 +0200 Subject: [PATCH 1/3] refactor: portfolio batcher to use fetchWithTimeout --- src/libs/portfolio/batcher.ts | 29 ++++++++++++++--------------- src/utils/fetch.ts | 13 +++++++++++++ 2 files changed, 27 insertions(+), 15 deletions(-) create mode 100644 src/utils/fetch.ts diff --git a/src/libs/portfolio/batcher.ts b/src/libs/portfolio/batcher.ts index ad9115778..b1c3f4f3e 100644 --- a/src/libs/portfolio/batcher.ts +++ b/src/libs/portfolio/batcher.ts @@ -1,4 +1,5 @@ import { Fetch } from '../../interfaces/fetch' +import { fetchWithTimeout } from '../../utils/fetch' export interface QueueElement { resolve: Function @@ -37,11 +38,16 @@ export default function batcher( // useful also if the API is limited to a certain # and we want to paginate requestGenerator(queueCopy).map(async ({ url, queueSegment }) => { try { - const fetchPromise = fetch(url).then(async (resp) => { + const fetchPromise = fetchWithTimeout( + fetch, + url, + {}, + timeoutSettings?.timeoutAfter || 20000 + ).then(async (resp) => { const body = await resp.json() if (resp.status !== 200) throw body - if (body.hasOwnProperty('message')) throw body - if (body.hasOwnProperty('error')) throw body + if (Object.prototype.hasOwnProperty.call(body, 'message')) throw body + if (Object.prototype.hasOwnProperty.call(body, 'error')) throw body if (Array.isArray(body)) { if (body.length !== queueSegment.length) throw new Error('internal error: queue length and response length mismatch') @@ -53,19 +59,12 @@ export default function batcher( } else throw body }) - if (timeoutSettings) { - const timeoutPromise = new Promise((_, reject) => { - setTimeout(() => { - reject(new Error('Request timed out')) - }, timeoutSettings.timeoutAfter) - }) - await Promise.race([fetchPromise, timeoutPromise]) - } else { - await fetchPromise - } + await fetchPromise } catch (e: any) { - if (e.message === 'Request timed out' && timeoutSettings) { - console.error(timeoutSettings.timeoutErrorMessage) + if (e.message === 'request-timeout' && timeoutSettings) { + console.error('Batcher error: ', timeoutSettings.timeoutErrorMessage) + } else { + console.log('Batcher error:', e) } queueSegment.forEach(({ reject }) => reject(e)) } diff --git a/src/utils/fetch.ts b/src/utils/fetch.ts new file mode 100644 index 000000000..5ed321d67 --- /dev/null +++ b/src/utils/fetch.ts @@ -0,0 +1,13 @@ +const fetchWithTimeout = async ( + fetch: Function, + url: string, + options: RequestInit, + timeout: number +): Promise => { + return new Promise((resolve, reject) => { + fetch(url, options).then(resolve).catch(reject) + setTimeout(() => reject(new Error('request-timeout')), timeout) + }) +} + +export { fetchWithTimeout } From c32142d080d4a7a6988c52e3c14ac5867e2414e0 Mon Sep 17 00:00:00 2001 From: Petromir Petrov Date: Fri, 13 Dec 2024 17:50:31 +0200 Subject: [PATCH 2/3] update: fetchWithTimeout --- src/utils/fetch.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/utils/fetch.ts b/src/utils/fetch.ts index 5ed321d67..7cbf01334 100644 --- a/src/utils/fetch.ts +++ b/src/utils/fetch.ts @@ -3,11 +3,14 @@ const fetchWithTimeout = async ( url: string, options: RequestInit, timeout: number -): Promise => { - return new Promise((resolve, reject) => { - fetch(url, options).then(resolve).catch(reject) - setTimeout(() => reject(new Error('request-timeout')), timeout) +): Promise => { + const timeoutPromise = new Promise((_, reject) => { + setTimeout(() => { + reject(new Error('request-timeout')) + }, timeout) }) + + return Promise.race([fetch(url, options), timeoutPromise]) } export { fetchWithTimeout } From d151ae2c9191aa2aab743fd8b9d4559228f2bae6 Mon Sep 17 00:00:00 2001 From: Petromir Petrov Date: Fri, 13 Dec 2024 17:53:01 +0200 Subject: [PATCH 3/3] update: fetchWithTimeout --- src/utils/fetch.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/fetch.ts b/src/utils/fetch.ts index 7cbf01334..e54cd4052 100644 --- a/src/utils/fetch.ts +++ b/src/utils/fetch.ts @@ -3,7 +3,7 @@ const fetchWithTimeout = async ( url: string, options: RequestInit, timeout: number -): Promise => { +): Promise => { const timeoutPromise = new Promise((_, reject) => { setTimeout(() => { reject(new Error('request-timeout'))