documenso/packages/lib/utils/timeout.ts

38 lines
1 KiB
TypeScript
Raw Normal View History

/**
* Race a promise against a timeout. Returns `null` if the timeout
* fires before the promise settles.
*/
export const withTimeout = async <T>(promise: Promise<T>, timeoutMs: number) =>
await Promise.race<T | null>([
promise,
new Promise<null>((resolve) => {
setTimeout(() => resolve(null), timeoutMs);
}),
]);
/**
* Wrapper around `fetch` that aborts the request after `timeoutMs`.
* Throws with a descriptive message on timeout.
*/
export const fetchWithTimeout = async (
input: string | URL | Request,
init: RequestInit & { timeoutMs: number },
) => {
const { timeoutMs, ...fetchInit } = init;
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), timeoutMs);
try {
return await fetch(input, { ...fetchInit, signal: controller.signal });
} catch (err) {
if (err instanceof DOMException && err.name === 'AbortError') {
throw new Error(`Request timed out after ${timeoutMs}ms`);
}
throw err;
} finally {
clearTimeout(timeout);
}
};