Skip to content

Instantly share code, notes, and snippets.

@southpolesteve
Created March 16, 2019 19:19
Show Gist options
  • Save southpolesteve/86d766bc2a6ea8e7aca7920217421084 to your computer and use it in GitHub Desktop.
Save southpolesteve/86d766bc2a6ea8e7aca7920217421084 to your computer and use it in GitHub Desktop.
User Abortable Fetch with Timeout
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