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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user