GeezerVison is showing github.com — timers: fix validation · nodejs/node@f524b8a
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: doc/api/timers.md +2-3Lines changed: 2 additions & 3 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
@@ -528,9 +528,8 @@ added: | 528 | 528 | An experimental API defined by the [Scheduling APIs][] draft specification | 529 | 529 | being developed as a standard Web Platform API. | 530 | 530 |
| 531 | | -Calling `timersPromises.scheduler.wait(delay, options)` is roughly equivalent | 532 | | -to calling `timersPromises.setTimeout(delay, undefined, options)` except that | 533 | | -the `ref` option is not supported. | | 531 | +Calling `timersPromises.scheduler.wait(delay, options)` is equivalent | | 532 | +to calling `timersPromises.setTimeout(delay, undefined, options)`. | 534 | 533 |
| 535 | 534 | ```mjs | 536 | 535 | import { scheduler } from 'node:timers/promises'; | |
Collapse file Copy file name to clipboardExpand all lines: lib/timers/promises.js +51-40Lines changed: 51 additions & 40 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -24,7 +24,6 @@ const { | 24 | 24 | AbortError, | 25 | 25 | codes: { | 26 | 26 | ERR_ILLEGAL_CONSTRUCTOR, | 27 | | - ERR_INVALID_ARG_TYPE, | 28 | 27 | ERR_INVALID_THIS, | 29 | 28 | }, | 30 | 29 | } = require('internal/errors'); | @@ -33,6 +32,7 @@ const { | 33 | 32 | validateAbortSignal, | 34 | 33 | validateBoolean, | 35 | 34 | validateObject, | | 35 | + validateNumber, | 36 | 36 | } = require('internal/validators'); | 37 | 37 |
| 38 | 38 | const { | @@ -50,34 +50,33 @@ function cancelListenerHandler(clear, reject, signal) { | 50 | 50 | } | 51 | 51 |
| 52 | 52 | function setTimeout(after, value, options = kEmptyObject) { | 53 | | - const args = value !== undefined ? [value] : value; | 54 | | - if (options == null || typeof options !== 'object') { | 55 | | - return PromiseReject( | 56 | | - new ERR_INVALID_ARG_TYPE( | 57 | | - 'options', | 58 | | - 'Object', | 59 | | - options)); | 60 | | - } | 61 | | - const { signal, ref = true } = options; | 62 | 53 | try { | 63 | | - validateAbortSignal(signal, 'options.signal'); | | 54 | + if (typeof after !== 'undefined') { | | 55 | + validateNumber(after, 'delay'); | | 56 | + } | | 57 | + | | 58 | + validateObject(options, 'options'); | | 59 | + | | 60 | + if (typeof options?.signal !== 'undefined') { | | 61 | + validateAbortSignal(options.signal, 'options.signal'); | | 62 | + } | | 63 | + | | 64 | + if (typeof options?.ref !== 'undefined') { | | 65 | + validateBoolean(options.ref, 'options.ref'); | | 66 | + } | 64 | 67 | } catch (err) { | 65 | 68 | return PromiseReject(err); | 66 | 69 | } | 67 | | - if (typeof ref !== 'boolean') { | 68 | | - return PromiseReject( | 69 | | - new ERR_INVALID_ARG_TYPE( | 70 | | - 'options.ref', | 71 | | - 'boolean', | 72 | | - ref)); | 73 | | - } | | 70 | + | | 71 | + const { signal, ref = true } = options; | 74 | 72 |
| 75 | 73 | if (signal?.aborted) { | 76 | 74 | return PromiseReject(new AbortError(undefined, { cause: signal.reason })); | 77 | 75 | } | | 76 | + | 78 | 77 | let oncancel; | 79 | 78 | const ret = new Promise((resolve, reject) => { | 80 | | - const timeout = new Timeout(resolve, after, args, false, ref); | | 79 | + const timeout = new Timeout(resolve, after, [value], false, ref); | 81 | 80 | insert(timeout, timeout._idleTimeout); | 82 | 81 | if (signal) { | 83 | 82 | oncancel = FunctionPrototypeBind(cancelListenerHandler, | @@ -93,30 +92,26 @@ function setTimeout(after, value, options = kEmptyObject) { | 93 | 92 | } | 94 | 93 |
| 95 | 94 | function setImmediate(value, options = kEmptyObject) { | 96 | | - if (options == null || typeof options !== 'object') { | 97 | | - return PromiseReject( | 98 | | - new ERR_INVALID_ARG_TYPE( | 99 | | - 'options', | 100 | | - 'Object', | 101 | | - options)); | 102 | | - } | 103 | | - const { signal, ref = true } = options; | 104 | 95 | try { | 105 | | - validateAbortSignal(signal, 'options.signal'); | | 96 | + validateObject(options, 'options'); | | 97 | + | | 98 | + if (typeof options?.signal !== 'undefined') { | | 99 | + validateAbortSignal(options.signal, 'options.signal'); | | 100 | + } | | 101 | + | | 102 | + if (typeof options?.ref !== 'undefined') { | | 103 | + validateBoolean(options.ref, 'options.ref'); | | 104 | + } | 106 | 105 | } catch (err) { | 107 | 106 | return PromiseReject(err); | 108 | 107 | } | 109 | | - if (typeof ref !== 'boolean') { | 110 | | - return PromiseReject( | 111 | | - new ERR_INVALID_ARG_TYPE( | 112 | | - 'options.ref', | 113 | | - 'boolean', | 114 | | - ref)); | 115 | | - } | | 108 | + | | 109 | + const { signal, ref = true } = options; | 116 | 110 |
| 117 | 111 | if (signal?.aborted) { | 118 | 112 | return PromiseReject(new AbortError(undefined, { cause: signal.reason })); | 119 | 113 | } | | 114 | + | 120 | 115 | let oncancel; | 121 | 116 | const ret = new Promise((resolve, reject) => { | 122 | 117 | const immediate = new Immediate(resolve, [value]); | @@ -136,13 +131,29 @@ function setImmediate(value, options = kEmptyObject) { | 136 | 131 | } | 137 | 132 |
| 138 | 133 | async function* setInterval(after, value, options = kEmptyObject) { | 139 | | - validateObject(options, 'options'); | | 134 | + try { | | 135 | + if (typeof after !== 'undefined') { | | 136 | + validateNumber(after, 'delay'); | | 137 | + } | | 138 | + | | 139 | + validateObject(options, 'options'); | | 140 | + | | 141 | + if (typeof options?.signal !== 'undefined') { | | 142 | + validateAbortSignal(options.signal, 'options.signal'); | | 143 | + } | | 144 | + | | 145 | + if (typeof options?.ref !== 'undefined') { | | 146 | + validateBoolean(options.ref, 'options.ref'); | | 147 | + } | | 148 | + } catch (err) { | | 149 | + return PromiseReject(err); | | 150 | + } | | 151 | + | 140 | 152 | const { signal, ref = true } = options; | 141 | | - validateAbortSignal(signal, 'options.signal'); | 142 | | - validateBoolean(ref, 'options.ref'); | 143 | 153 |
| 144 | | - if (signal?.aborted) | | 154 | + if (signal?.aborted) { | 145 | 155 | throw new AbortError(undefined, { cause: signal?.reason }); | | 156 | + } | 146 | 157 |
| 147 | 158 | let onCancel; | 148 | 159 | let interval; | @@ -216,7 +227,7 @@ class Scheduler { | 216 | 227 | wait(delay, options) { | 217 | 228 | if (!this[kScheduler]) | 218 | 229 | throw new ERR_INVALID_THIS('Scheduler'); | 219 | | - return setTimeout(delay, undefined, { signal: options?.signal }); | | 230 | + return setTimeout(delay, undefined, options); | 220 | 231 | } | 221 | 232 | } | 222 | 233 |
| |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-timers-timeout-promisified.js +15-23Lines changed: 15 additions & 23 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -63,29 +63,21 @@ process.on('multipleResolves', common.mustNotCall()); | 63 | 63 | } | 64 | 64 |
| 65 | 65 | { | 66 | | - Promise.all( | 67 | | - [1, '', false, Infinity].map( | 68 | | - (i) => assert.rejects(setPromiseTimeout(10, null, i), { | 69 | | - code: 'ERR_INVALID_ARG_TYPE' | 70 | | - }) | 71 | | - ) | 72 | | - ).then(common.mustCall()); | 73 | | - | 74 | | - Promise.all( | 75 | | - [1, '', false, Infinity, null, {}].map( | 76 | | - (signal) => assert.rejects(setPromiseTimeout(10, null, { signal }), { | 77 | | - code: 'ERR_INVALID_ARG_TYPE' | 78 | | - }) | 79 | | - ) | 80 | | - ).then(common.mustCall()); | 81 | | - | 82 | | - Promise.all( | 83 | | - [1, '', Infinity, null, {}].map( | 84 | | - (ref) => assert.rejects(setPromiseTimeout(10, null, { ref }), { | 85 | | - code: 'ERR_INVALID_ARG_TYPE' | 86 | | - }) | 87 | | - ) | 88 | | - ).then(common.mustCall()); | | 66 | + for (const delay of ['', false]) { | | 67 | + assert.rejects(() => setPromiseTimeout(delay, null, {}), /ERR_INVALID_ARG_TYPE/).then(common.mustCall()); | | 68 | + } | | 69 | + | | 70 | + for (const options of [1, '', false, Infinity]) { | | 71 | + assert.rejects(() => setPromiseTimeout(10, null, options), /ERR_INVALID_ARG_TYPE/).then(common.mustCall()); | | 72 | + } | | 73 | + | | 74 | + for (const signal of [1, '', false, Infinity, null, {}]) { | | 75 | + assert.rejects(() => setPromiseTimeout(10, null, { signal }), /ERR_INVALID_ARG_TYPE/).then(common.mustCall()); | | 76 | + } | | 77 | + | | 78 | + for (const ref of [1, '', Infinity, null, {}]) { | | 79 | + assert.rejects(() => setPromiseTimeout(10, null, { ref }), /ERR_INVALID_ARG_TYPE/).then(common.mustCall()); | | 80 | + } | 89 | 81 | } | 90 | 82 |
| 91 | 83 | { | |
|