Created
March 16, 2019 19:19
-
-
Save southpolesteve/86d766bc2a6ea8e7aca7920217421084 to your computer and use it in GitHub Desktop.
User Abortable Fetch with Timeout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export async function userAbortableFetchWithTimeout(url: string, options?: any) { | |
// We need our own internal abort controller even if the user passed one | |
const controller = new AbortController(); | |
const signal = controller.signal; | |
// Setup timeout | |
const timeout = setTimeout(() => { | |
controller.abort(); | |
}, options.timeout); | |
// Wrap users passed abort events and call our own internal abort() | |
if (options.signal) { | |
// If the user already aborted, abort our internal signal | |
if (options.signal.aborted) { | |
controller.abort(); | |
} else { | |
// Listen for user passed signal | |
options.signal.addEventListener("abort", () => { | |
controller.abort(); | |
}); | |
} | |
} | |
let response: any; | |
try { | |
response = await fetch(url, { ...options, ...{ signal } }); | |
} catch (error) { | |
if (error.name === "AbortError") { | |
// If the user passed signal caused the abort, cancel the timeout and rethrow the error | |
if (options.signal && options.signal.aborted === true) { | |
clearTimeout(timeout); | |
throw error; | |
} | |
throw new TimeoutError(); | |
} | |
throw error; | |
} | |
// Clear abort timeout on successful request | |
clearTimeout(timeout); | |
return response; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment