-
Notifications
You must be signed in to change notification settings - Fork 213
/
Copy pathfetchWithTimeout.ts
56 lines (49 loc) · 1.11 KB
/
fetchWithTimeout.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import BaseError from './baseError';
export class TimeoutError extends BaseError {
constructor(msg: string) {
super('TimeoutError', msg);
}
}
function makeTimeout(timeoutMs: number) {
let timerId: NodeJS.Timeout | null = null;
const promise = new Promise((_, reject) => {
timerId = setTimeout(() => {
reject(new TimeoutError('Timeout'));
}, timeoutMs);
});
return {
timerId: timerId,
promise: promise,
};
}
/**
* @private
*/
export function fetchWithTimeout(
url: string,
options: RequestInit,
timeoutMs: number,
): Promise<Response> {
const {
promise: timeoutPromise,
timerId,
}: {promise: Promise<unknown>; timerId: any} = makeTimeout(timeoutMs);
const abortController = new AbortController();
return Promise.race([
fetch(url, {
...options,
signal: abortController.signal,
}),
timeoutPromise,
])
.catch((error) => {
if (error instanceof TimeoutError) {
abortController.abort();
}
throw error;
})
.then((response) => {
clearTimeout(timerId);
return response;
}) as Promise<Response>;
}