diff --git a/packages/insomnia/src/common/constants.ts b/packages/insomnia/src/common/constants.ts index 7f201938dfd..c8c0bedca27 100644 --- a/packages/insomnia/src/common/constants.ts +++ b/packages/insomnia/src/common/constants.ts @@ -590,3 +590,6 @@ export const EXPORT_TYPE_ENVIRONMENT = 'environment'; export const EXPORT_TYPE_API_SPEC = 'api_spec'; export const EXPORT_TYPE_PROTO_FILE = 'proto_file'; export const EXPORT_TYPE_PROTO_DIRECTORY = 'proto_directory'; + +// (ms) curently server timeout is 30s +export const INSOMNIA_FETCH_TIME_OUT = 30_000; diff --git a/packages/insomnia/src/ui/insomniaFetch.ts b/packages/insomnia/src/ui/insomniaFetch.ts index 48e25926bdb..d2d976cad35 100644 --- a/packages/insomnia/src/ui/insomniaFetch.ts +++ b/packages/insomnia/src/ui/insomniaFetch.ts @@ -1,6 +1,5 @@ -import { getApiBaseURL, getClientString, PLAYWRIGHT } from '../common/constants'; -import { delay } from '../common/misc'; +import { getApiBaseURL, getClientString, INSOMNIA_FETCH_TIME_OUT, PLAYWRIGHT } from '../common/constants'; interface FetchConfig { method: 'POST' | 'PUT' | 'GET' | 'DELETE' | 'PATCH'; @@ -13,26 +12,6 @@ interface FetchConfig { headers?: Record; } -const exponentialBackOff = async (url: string, init: RequestInit, retries = 0): Promise => { - try { - const response = await fetch(url, init); - if (response.status === 502 && retries < 5) { - retries++; - await delay(retries * 1000); - console.log(`Received 502 from ${url} retrying`); - return exponentialBackOff(url, init, retries); - } - if (!response.ok) { - // TODO: review error status code behaviour with backend, should we parse errors here and return response - // or should we rethrow an error with a response object inside? should we be exposing errors to the app UI? - console.log(`Response not OK: ${response.status} for ${url}`); - } - return response; - } catch (err) { - throw err; - } -}; - // Adds headers, retries and opens deep links returned from the api export async function insomniaFetch({ method, path, data, sessionId, organizationId, origin, headers }: FetchConfig): Promise { const config: RequestInit = { @@ -47,15 +26,25 @@ export async function insomniaFetch({ method, path, data, sessionId, o ...(PLAYWRIGHT ? { 'X-Mockbin-Test': 'true' } : {}), }, ...(data ? { body: JSON.stringify(data) } : {}), + signal: AbortSignal.timeout(INSOMNIA_FETCH_TIME_OUT), }; if (sessionId === undefined) { throw new Error(`No session ID provided to ${method}:${path}`); } - const response = await exponentialBackOff((origin || getApiBaseURL()) + path, config); - const uri = response.headers.get('x-insomnia-command'); - if (uri) { - window.main.openDeepLink(uri); + + try { + const response = await fetch((origin || getApiBaseURL()) + path, config); + const uri = response.headers.get('x-insomnia-command'); + if (uri) { + window.main.openDeepLink(uri); + } + const isJson = response.headers.get('content-type')?.includes('application/json') || path.match(/\.json$/); + return isJson ? response.json() : response.text(); + } catch (err) { + if (err.name === 'AbortError') { + throw new Error('insomniaFetch timed out'); + } else { + throw err; + } } - const isJson = response.headers.get('content-type')?.includes('application/json') || path.match(/\.json$/); - return isJson ? response.json() : response.text(); }