Async Timeout Wrapper
Race a promise against a timer so a slow dependency cannot hold a request open indefinitely, aborting the underlying signal when the deadline passes.
Code
export async function withTimeout(promiseFactory, timeoutMs, signal) {
const controller = new AbortController();
if (signal) signal.addEventListener("abort", () => controller.abort());
let timer;
const timerPromise = new Promise((_, reject) => {
timer = setTimeout(() => {
controller.abort();
reject(new Error("operation timed out after " + timeoutMs + "ms"));
}, timeoutMs);
});
try {
return await Promise.race([promiseFactory(controller.signal), timerPromise]);
} finally {
clearTimeout(timer);
}
}Report a problem with this exampleOpens a pre-filled issue on GitHub.