blob: fa48cc7b1d219985b512797176d0ee45f254b757 [file] [log] [blame]
Leo Repp58b9f112021-11-22 11:57:47 +01001'use strict';
2const pFinally = require('p-finally');
3
4class TimeoutError extends Error {
5 constructor(message) {
6 super(message);
7 this.name = 'TimeoutError';
8 }
9}
10
11module.exports = (promise, ms, fallback) => new Promise((resolve, reject) => {
12 if (typeof ms !== 'number' || ms < 0) {
13 throw new TypeError('Expected `ms` to be a positive number');
14 }
15
16 const timer = setTimeout(() => {
17 if (typeof fallback === 'function') {
18 resolve(fallback());
19 return;
20 }
21
22 const message = typeof fallback === 'string' ? fallback : `Promise timed out after ${ms} milliseconds`;
23 const err = fallback instanceof Error ? fallback : new TimeoutError(message);
24
25 reject(err);
26 }, ms);
27
28 pFinally(
29 promise.then(resolve, reject),
30 () => {
31 clearTimeout(timer);
32 }
33 );
34});
35
36module.exports.TimeoutError = TimeoutError;