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 } = {}) { | export async function fetchWithTimeout (resource, { timeout = 1000, ...options } = {}) { | ||||||
|   const controller = new AbortController() |   try { | ||||||
|   const id = setTimeout(() => controller.abort(), timeout) |     return await fetch(resource, { | ||||||
| 
 |       ...options, | ||||||
|   const response = await fetch(resource, { |       signal: AbortSignal.timeout(timeout) | ||||||
|     ...options, |     }) | ||||||
|     signal: controller.signal |   } catch (err) { | ||||||
|   }) |     if (err.name === 'TimeoutError') { | ||||||
|   clearTimeout(id) |       // use custom error message
 | ||||||
| 
 |       throw new FetchTimeoutError('GET', resource, timeout) | ||||||
|   return response |     } | ||||||
|  |     throw err | ||||||
|  |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class LRUCache { | class LRUCache { | ||||||
|  | |||||||
| @ -128,6 +128,13 @@ function tzOffset (tz) { | |||||||
|   return targetOffsetHours |   return targetOffsetHours | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | export class TimeoutError extends Error { | ||||||
|  |   constructor (timeout) { | ||||||
|  |     super(`timeout after ${timeout / 1000}s`) | ||||||
|  |     this.name = 'TimeoutError' | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| function timeoutPromise (timeout) { | function timeoutPromise (timeout) { | ||||||
|   return new Promise((resolve, reject) => { |   return new Promise((resolve, reject) => { | ||||||
|     // if no timeout is specified, never settle
 |     // if no timeout is specified, never settle
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user