Use AbortSignal.timeout + custom timeout error message (#1718)
* refactor: replace custom logic with AbortSignal.timeout * Use custom timeout error message * Include method and url in fetch timeout error * Fix error not rethrown
This commit is contained in:
parent
e8434d07c5
commit
fc4303658d
32
lib/fetch.js
32
lib/fetch.js
|
@ -1,14 +1,26 @@
|
|||
import { TimeoutError } from '@/lib/time'
|
||||
|
||||
class FetchTimeoutError extends TimeoutError {
|
||||
constructor (method, url, timeout) {
|
||||
super(timeout)
|
||||
this.name = 'FetchTimeoutError'
|
||||
this.message = `${method} ${url}: timeout after ${timeout / 1000}s`
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchWithTimeout (resource, { timeout = 1000, ...options } = {}) {
|
||||
const controller = new AbortController()
|
||||
const id = setTimeout(() => controller.abort(), timeout)
|
||||
|
||||
const response = await fetch(resource, {
|
||||
...options,
|
||||
signal: controller.signal
|
||||
})
|
||||
clearTimeout(id)
|
||||
|
||||
return response
|
||||
try {
|
||||
return await fetch(resource, {
|
||||
...options,
|
||||
signal: AbortSignal.timeout(timeout)
|
||||
})
|
||||
} catch (err) {
|
||||
if (err.name === 'TimeoutError') {
|
||||
// use custom error message
|
||||
throw new FetchTimeoutError('GET', resource, timeout)
|
||||
}
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
class LRUCache {
|
||||
|
|
|
@ -128,6 +128,13 @@ function tzOffset (tz) {
|
|||
return targetOffsetHours
|
||||
}
|
||||
|
||||
export class TimeoutError extends Error {
|
||||
constructor (timeout) {
|
||||
super(`timeout after ${timeout / 1000}s`)
|
||||
this.name = 'TimeoutError'
|
||||
}
|
||||
}
|
||||
|
||||
function timeoutPromise (timeout) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// if no timeout is specified, never settle
|
||||
|
|
Loading…
Reference in New Issue