@beignet/core
Version:
Core framework primitives for Beignet
48 lines (41 loc) • 1.42 kB
text/typescript
type MaybePromise<T> = T | Promise<T>;
export const DEFAULT_ERROR_REPORTING_TIMEOUT_MS = 1000;
export class ErrorReportingTimeoutError extends Error {
readonly code = "ERROR_REPORTING_TIMEOUT" as const;
readonly timeoutMs: number;
constructor(timeoutMs: number) {
super(`Error reporting timed out after ${timeoutMs}ms.`);
this.name = "ErrorReportingTimeoutError";
this.timeoutMs = timeoutMs;
}
}
export function errorReportingObserverTimeout(
timeoutMs: number | false,
): number | false {
return timeoutMs === false || (Number.isFinite(timeoutMs) && timeoutMs > 0)
? timeoutMs
: DEFAULT_ERROR_REPORTING_TIMEOUT_MS;
}
export async function runErrorReportingOperation<T>(
operation: () => MaybePromise<T>,
timeoutMs: number | false = DEFAULT_ERROR_REPORTING_TIMEOUT_MS,
): Promise<T> {
if (timeoutMs === false) return operation();
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
throw new TypeError("Error reporting timeoutMs must be a positive number.");
}
let timeout: ReturnType<typeof setTimeout> | undefined;
try {
return await Promise.race([
Promise.resolve().then(operation),
new Promise<never>((_, reject) => {
timeout = setTimeout(
() => reject(new ErrorReportingTimeoutError(timeoutMs)),
timeoutMs,
);
}),
]);
} finally {
if (timeout !== undefined) clearTimeout(timeout);
}
}