export class TimeoutError extends Error { readonly timeoutMs: number; constructor(operationName: string, timeoutMs: number) { super(`${operationName} timed out after ${timeoutMs}ms`); this.name = "TimeoutError"; this.timeoutMs = timeoutMs; } } export async function withTimeout( operation: () => Promise, { operationName, timeoutMs }: { operationName: string; timeoutMs: number; } ): Promise { let timer: NodeJS.Timeout | undefined; try { return await Promise.race([ operation(), new Promise((_, reject) => { timer = setTimeout(() => { reject(new TimeoutError(operationName, timeoutMs)); }, timeoutMs); }) ]); } finally { if (timer) { clearTimeout(timer); } } }