Skip to content

Commit

Permalink
timers: fix validation
Browse files Browse the repository at this point in the history
  • Loading branch information
ShogunPanda committed Aug 24, 2024
1 parent a21af4b commit f26240f
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 67 deletions.
5 changes: 2 additions & 3 deletions doc/api/timers.md
Original file line number Diff line number Diff line change
Expand Up @@ -532,9 +532,8 @@ added:
An experimental API defined by the [Scheduling APIs][] draft specification
being developed as a standard Web Platform API.

Calling `timersPromises.scheduler.wait(delay, options)` is roughly equivalent
to calling `timersPromises.setTimeout(delay, undefined, options)` except that
the `ref` option is not supported.
Calling `timersPromises.scheduler.wait(delay, options)` is equivalent
to calling `timersPromises.setTimeout(delay, undefined, options)`.

```mjs
import { scheduler } from 'node:timers/promises';
Expand Down
94 changes: 53 additions & 41 deletions lib/timers/promises.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const {
validateAbortSignal,
validateBoolean,
validateObject,
validateNumber,
} = require('internal/validators');

const {
Expand All @@ -50,34 +51,33 @@ function cancelListenerHandler(clear, reject, signal) {
}

function setTimeout(after, value, options = kEmptyObject) {
const args = value !== undefined ? [value] : value;
if (options == null || typeof options !== 'object') {
return PromiseReject(
new ERR_INVALID_ARG_TYPE(
'options',
'Object',
options));
}
const { signal, ref = true } = options;
try {
validateAbortSignal(signal, 'options.signal');
} catch (err) {
if(typeof after !== 'undefined') {

Check failure on line 55 in lib/timers/promises.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Expected space(s) after "if"
validateNumber(after, 'delay');
}

Check failure on line 58 in lib/timers/promises.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Trailing spaces not allowed
validateObject(options, 'options');

Check failure on line 60 in lib/timers/promises.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Trailing spaces not allowed
if(typeof options?.signal !== 'undefined') {

Check failure on line 61 in lib/timers/promises.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Expected space(s) after "if"
validateAbortSignal(options.signal, 'options.signal');
}

if(typeof options?.ref !== 'undefined') {

Check failure on line 65 in lib/timers/promises.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Expected space(s) after "if"
validateBoolean(options.ref, 'options.ref');
}
}catch (err) {

Check failure on line 68 in lib/timers/promises.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Expected space(s) before "catch"
return PromiseReject(err);
}
if (typeof ref !== 'boolean') {
return PromiseReject(
new ERR_INVALID_ARG_TYPE(
'options.ref',
'boolean',
ref));
}

const { signal, ref = true } = options;

if (signal?.aborted) {
return PromiseReject(new AbortError(undefined, { cause: signal.reason }));
}

let oncancel;
const ret = new Promise((resolve, reject) => {
const timeout = new Timeout(resolve, after, args, false, ref);
const timeout = new Timeout(resolve, after, [value], false, ref);
insert(timeout, timeout._idleTimeout);
if (signal) {
oncancel = FunctionPrototypeBind(cancelListenerHandler,
Expand All @@ -93,30 +93,26 @@ function setTimeout(after, value, options = kEmptyObject) {
}

function setImmediate(value, options = kEmptyObject) {
if (options == null || typeof options !== 'object') {
return PromiseReject(
new ERR_INVALID_ARG_TYPE(
'options',
'Object',
options));
}
const { signal, ref = true } = options;
try {
validateAbortSignal(signal, 'options.signal');
} catch (err) {
validateObject(options, 'options');

Check failure on line 98 in lib/timers/promises.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Trailing spaces not allowed
if(typeof options?.signal !== 'undefined') {

Check failure on line 99 in lib/timers/promises.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Expected space(s) after "if"
validateAbortSignal(options.signal, 'options.signal');
}

if(typeof options?.ref !== 'undefined') {

Check failure on line 103 in lib/timers/promises.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Expected space(s) after "if"
validateBoolean(options.ref, 'options.ref');
}
}catch (err) {
return PromiseReject(err);
}
if (typeof ref !== 'boolean') {
return PromiseReject(
new ERR_INVALID_ARG_TYPE(
'options.ref',
'boolean',
ref));
}

const { signal, ref = true } = options;

if (signal?.aborted) {
return PromiseReject(new AbortError(undefined, { cause: signal.reason }));
}

let oncancel;
const ret = new Promise((resolve, reject) => {
const immediate = new Immediate(resolve, [value]);
Expand All @@ -136,13 +132,29 @@ function setImmediate(value, options = kEmptyObject) {
}

async function* setInterval(after, value, options = kEmptyObject) {
validateObject(options, 'options');
try {
if(typeof after !== 'undefined') {
validateNumber(after, 'delay');
}

validateObject(options, 'options');

if(typeof options?.signal !== 'undefined') {
validateAbortSignal(options.signal, 'options.signal');
}

if(typeof options?.ref !== 'undefined') {
validateBoolean(options.ref, 'options.ref');
}
}catch (err) {
return PromiseReject(err);
}

const { signal, ref = true } = options;
validateAbortSignal(signal, 'options.signal');
validateBoolean(ref, 'options.ref');

if (signal?.aborted)
if (signal?.aborted) {
throw new AbortError(undefined, { cause: signal?.reason });
}

let onCancel;
let interval;
Expand Down Expand Up @@ -216,7 +228,7 @@ class Scheduler {
wait(delay, options) {
if (!this[kScheduler])
throw new ERR_INVALID_THIS('Scheduler');
return setTimeout(delay, undefined, { signal: options?.signal });
return setTimeout(delay, undefined, options);
}
}

Expand Down
38 changes: 15 additions & 23 deletions test/parallel/test-timers-timeout-promisified.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,29 +63,21 @@ process.on('multipleResolves', common.mustNotCall());
}

{
Promise.all(
[1, '', false, Infinity].map(
(i) => assert.rejects(setPromiseTimeout(10, null, i), {
code: 'ERR_INVALID_ARG_TYPE'
})
)
).then(common.mustCall());

Promise.all(
[1, '', false, Infinity, null, {}].map(
(signal) => assert.rejects(setPromiseTimeout(10, null, { signal }), {
code: 'ERR_INVALID_ARG_TYPE'
})
)
).then(common.mustCall());

Promise.all(
[1, '', Infinity, null, {}].map(
(ref) => assert.rejects(setPromiseTimeout(10, null, { ref }), {
code: 'ERR_INVALID_ARG_TYPE'
})
)
).then(common.mustCall());
for(const delay of ['', false]) {
assert.rejects(() => setPromiseTimeout(delay, null, {}), /ERR_INVALID_ARG_TYPE/).then(common.mustCall());
}

for(const options of [1, '', false, Infinity]) {
assert.rejects(() => setPromiseTimeout(10, null, options), /ERR_INVALID_ARG_TYPE/).then(common.mustCall());
}

for(const signal of [1, '', false, Infinity, null, {}]) {
assert.rejects(() => setPromiseTimeout(10, null, { signal }), /ERR_INVALID_ARG_TYPE/).then(common.mustCall());
}

for(const ref of [1, '', Infinity, null, {}]) {
assert.rejects(() => setPromiseTimeout(10, null, { ref }), /ERR_INVALID_ARG_TYPE/).then(common.mustCall());
}
}

{
Expand Down

0 comments on commit f26240f

Please sign in to comment.