/
http-utils.ts
45 lines (39 loc) · 1.15 KB
/
http-utils.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
import fetch from 'cross-fetch'
// TODO: remove with esm upgrade
import AbortController from 'abort-controller'
const DEFAULT_FETCH_TIMEOUT = 60 * 1000 * 3 // 3 minutes
interface FetchOpts {
body?: any
method?: string
headers?: any
timeout?: number
}
export async function fetchJson(url: string, opts: FetchOpts = {}): Promise<any> {
if (opts.body) {
Object.assign(opts, {
body: JSON.stringify(opts.body),
headers: { 'Content-Type': 'application/json' },
})
}
const timeoutLength = opts.timeout || DEFAULT_FETCH_TIMEOUT
const controller = new AbortController()
const timeout = setTimeout(() => {
controller.abort()
}, timeoutLength)
Object.assign(opts, {
signal: controller.signal,
})
const res = await fetch(url, opts)
.catch((err) => {
if (err.name == 'AbortError') {
throw new Error(`Http request timed out after ${timeoutLength} ms`)
}
throw err
})
.finally(() => timeout && clearTimeout(timeout))
if (!res.ok) {
const text = await res.text()
throw new Error(`HTTP request to '${url}' failed with status '${res.statusText}': ${text}`)
}
return res.json()
}