Skip to content

Commit

Permalink
add AbortSignal for timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
gatzjames committed May 31, 2024
1 parent 7736bef commit 74e602e
Showing 1 changed file with 18 additions and 15 deletions.
33 changes: 18 additions & 15 deletions packages/insomnia/src/ui/insomniaFetch.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import { getApiBaseURL, getClientString, INSOMNIA_FETCH_RETRY_TIMES, INSOMNIA_FETCH_TIME_OUT, PLAYWRIGHT } from '../common/constants';
import { delay } from '../common/misc';

Expand All @@ -14,18 +13,26 @@ interface FetchConfig {
}

// we need to retry on 429 and 5xx errors
const needRetry = (httpCode: number, retries: number): boolean => {
return (httpCode === 429 || (httpCode >= 500 && httpCode < 600)) && retries < INSOMNIA_FETCH_RETRY_TIMES;
const needRetry = (httpCode: number, retriedCount: number): boolean => {
return (httpCode === 429 || httpCode >= 500) && retriedCount < INSOMNIA_FETCH_RETRY_TIMES;
};

const exponentialBackOff = async (url: string, init: RequestInit, retries = 0): Promise<Response> => {
const exponentialBackOff = async ({
url,
init,
retriedCount = 0,
}: {
url: string;
init: RequestInit;
retriedCount?: number;
}): Promise<Response> => {
try {
const response = await fetch(url, init);
if (needRetry(response.status, retries)) {
retries++;
await delay(retries * 1000);
if (needRetry(response.status, retriedCount)) {
retriedCount++;
await delay(500);
console.log(`Received ${response.status} from ${url} retrying`);
return exponentialBackOff(url, init, retries);
return exponentialBackOff({ url, init, retriedCount });
}
if (!response.ok) {
// TODO: review error status code behaviour with backend, should we parse errors here and return response
Expand All @@ -40,8 +47,6 @@ const exponentialBackOff = async (url: string, init: RequestInit, retries = 0):

// Adds headers, retries and opens deep links returned from the api
export async function insomniaFetch<T = void>({ method, path, data, sessionId, organizationId, origin, headers }: FetchConfig): Promise<T> {
const controller = new AbortController();
const signal = controller.signal;
const config: RequestInit = {
method,
headers: {
Expand All @@ -54,24 +59,22 @@ export async function insomniaFetch<T = void>({ method, path, data, sessionId, o
...(PLAYWRIGHT ? { 'X-Mockbin-Test': 'true' } : {}),
},
...(data ? { body: JSON.stringify(data) } : {}),
signal,
signal: AbortSignal.timeout(INSOMNIA_FETCH_TIME_OUT),
};

if (sessionId === undefined) {
throw new Error(`No session ID provided to ${method}:${path}`);
}
const timeoutId = setTimeout(() => controller.abort(), INSOMNIA_FETCH_TIME_OUT);

try {
const response = await exponentialBackOff((origin || getApiBaseURL()) + path, config);
clearTimeout(timeoutId);
const response = await exponentialBackOff({ url: (origin || getApiBaseURL()) + path, init: 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) {
clearTimeout(timeoutId);
if (err.name === 'AbortError') {
throw new Error('insomniaFetch timed out');
} else {
Expand Down

0 comments on commit 74e602e

Please sign in to comment.