Skip to content

Commit 45405e7

Browse files
Allow timing out without erroring (#30)
Co-authored-by: Sindre Sorhus <[email protected]>
1 parent 200df03 commit 45405e7

File tree

5 files changed

+52
-10
lines changed

5 files changed

+52
-10
lines changed

index.d.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,23 @@ export type Options<ReturnType> = {
4343
fallback?: () => ReturnType | Promise<ReturnType>;
4444

4545
/**
46-
Specify a custom error message or error.
46+
Specify a custom error message or error to throw when it times out:
4747
48-
If you do a custom error, it's recommended to sub-class `pTimeout.TimeoutError`.
48+
- `message: 'too slow'` will throw `TimeoutError('too slow')`
49+
- `message: new MyCustomError('it’s over 9000')` will throw the same error instance
50+
- `message: false` will make the promise resolve with `undefined` instead of rejecting
51+
52+
If you do a custom error, it's recommended to sub-class `TimeoutError`:
53+
54+
```
55+
import {TimeoutError} from 'p-timeout';
56+
57+
class MyCustomError extends TimeoutError {
58+
name = "MyCustomError";
59+
}
60+
```
4961
*/
50-
message?: string | Error;
62+
message?: string | Error | false;
5163

5264
/**
5365
Custom implementations for the `setTimeout` and `clearTimeout` functions.
@@ -129,6 +141,10 @@ await pTimeout(delayedPromise(), {
129141
});
130142
```
131143
*/
144+
export default function pTimeout<ValueType, ReturnType = ValueType>(
145+
input: PromiseLike<ValueType>,
146+
options: Options<ReturnType> & {message: false}
147+
): ClearablePromise<ValueType | ReturnType | undefined>;
132148
export default function pTimeout<ValueType, ReturnType = ValueType>(
133149
input: PromiseLike<ValueType>,
134150
options: Options<ReturnType>

index.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,18 @@ export default function pTimeout(promise, options) {
7777
return;
7878
}
7979

80-
const errorMessage = typeof message === 'string' ? message : `Promise timed out after ${milliseconds} milliseconds`;
81-
const timeoutError = message instanceof Error ? message : new TimeoutError(errorMessage);
82-
8380
if (typeof promise.cancel === 'function') {
8481
promise.cancel();
8582
}
8683

87-
reject(timeoutError);
84+
if (message === false) {
85+
resolve();
86+
} else if (message instanceof Error) {
87+
reject(message);
88+
} else {
89+
const errorMessage = message ?? `Promise timed out after ${milliseconds} milliseconds`;
90+
reject(new TimeoutError(errorMessage));
91+
}
8892
}, milliseconds);
8993

9094
(async () => {

index.test-d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ pTimeout(delayedPromise(), {milliseconds: 50}).then(value => {
1616
pTimeout(delayedPromise(), {milliseconds: 50, message: 'error'}).then(value => {
1717
expectType<string>(value);
1818
});
19+
pTimeout(delayedPromise(), {milliseconds: 50, message: false}).then(value => {
20+
expectType<string | undefined>(value);
21+
});
1922
pTimeout(delayedPromise(), {milliseconds: 50, message: new Error('error')}).then(value => {
2023
expectType<string>(value);
2124
});

readme.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,24 @@ Passing `Infinity` will cause it to never time out.
5050

5151
##### message
5252

53-
Type: `string | Error`\
53+
Type: `string | Error | false`\
5454
Default: `'Promise timed out after 50 milliseconds'`
5555

56-
Specify a custom error message or error.
56+
Specify a custom error message or error to throw when it times out:
5757

58-
If you do a custom error, it's recommended to sub-class `pTimeout.TimeoutError`.
58+
- `message: 'too slow'` will throw `TimeoutError('too slow')`
59+
- `message: new MyCustomError('it’s over 9000')` will throw the same error instance
60+
- `message: false` will make the promise resolve with `undefined` instead of rejecting
61+
62+
If you do a custom error, it's recommended to sub-class `TimeoutError`:
63+
64+
```js
65+
import {TimeoutError} from 'p-timeout';
66+
67+
class MyCustomError extends TimeoutError {
68+
name = "MyCustomError";
69+
}
70+
```
5971

6072
##### fallback
6173

test.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ test('rejects after timeout', async t => {
3535
await t.throwsAsync(pTimeout(delay(200), {milliseconds: 50}), {instanceOf: TimeoutError});
3636
});
3737

38+
test('resolves after timeout with message:false', async t => {
39+
t.is(
40+
await pTimeout(delay(200), {milliseconds: 50, message: false}),
41+
undefined,
42+
);
43+
});
44+
3845
test('rejects before timeout if specified promise rejects', async t => {
3946
await t.throwsAsync(pTimeout(delay(50).then(() => {
4047
throw fixtureError;

0 commit comments

Comments
 (0)