Skip to content

Instantly share code, notes, and snippets.

@jonasgeiler
Last active December 17, 2023 16:37
Show Gist options
  • Save jonasgeiler/e175e08515302759c6b0e39e1ab8c581 to your computer and use it in GitHub Desktop.
Save jonasgeiler/e175e08515302759c6b0e39e1ab8c581 to your computer and use it in GitHub Desktop.
A simple fetch() wrapper with timeout
/**
* A simple fetch() wrapper with timeout.
* @param input - Same as `fetch()`.
* @param init - Same as `fetch()`, but with an extra option `timeout` (defaults to no timeout).
* @returns - Same as `fetch()`.
*/
export const fetchWithTimeout = (input: RequestInfo, init?: RequestInit & { timeout?: number }) => {
if (typeof init?.timeout === 'number') {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(new TimeoutError()), init.timeout);
return fetch(input, {
signal: controller.signal,
...init,
}).finally(() => clearTimeout(timeoutId));
}
return fetch(input, init);
};
/** Custom timeout error for fetchWithTimeout() */
export class TimeoutError extends Error {
constructor() {
super('Failed to fetch');
this.name = 'TimeoutError';
}
}
@jonasgeiler
Copy link
Author

TODO:

  • Prevent passing custom signal in init which would override the timeout signal and break stuff (use Omit<> type)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment