@augment-vir/common
Version:
A collection of augments, helpers types, functions, and classes for any JavaScript environment.
55 lines (54 loc) • 1.91 kB
JavaScript
import { check } from '@augment-vir/assert';
import { ensureError } from '@augment-vir/core';
import { convertDuration } from '@date-vir/duration';
/**
* An error thrown by {@link wrapPromiseInTimeout} when the timeout is reached.
*
* @category Promise
* @category Package : @augment-vir/common
* @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common)
*/
export class PromiseTimeoutError extends Error {
duration;
name = 'PromiseTimeoutError';
constructor(duration, failureMessage) {
super([
failureMessage,
`Promised timed out after ${convertDuration(duration, { milliseconds: true }).milliseconds} ms.`,
]
.filter(check.isTruthy)
.join(': '));
this.duration = duration;
}
}
/**
* Wraps an already-created Promise in a timeout, causing a rejection if the original Promise isn't
* resolved by then.
*
* @category Promise
* @category Package : @augment-vir/common
* @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common)
*/
export function wrapPromiseInTimeout(duration, originalPromise, failureMessage) {
const isInfinity = Object.values(duration).some((value) => value && check.isInfinite(value));
const milliseconds = isInfinity
? Infinity
: convertDuration(duration, { milliseconds: true }).milliseconds;
return new Promise(async (resolve, reject) => {
const timeoutId = milliseconds === Infinity
? undefined
: setTimeout(() => {
reject(new PromiseTimeoutError(duration, failureMessage));
}, milliseconds);
try {
const result = await originalPromise;
resolve(result);
}
catch (error) {
reject(ensureError(error));
}
finally {
clearTimeout(timeoutId);
}
});
}