-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
timers: fix validation #54404
timers: fix validation #54404
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,7 +24,6 @@ const { | |
AbortError, | ||
codes: { | ||
ERR_ILLEGAL_CONSTRUCTOR, | ||
ERR_INVALID_ARG_TYPE, | ||
ERR_INVALID_THIS, | ||
}, | ||
} = require('internal/errors'); | ||
|
@@ -33,6 +32,7 @@ const { | |
validateAbortSignal, | ||
validateBoolean, | ||
validateObject, | ||
validateNumber, | ||
} = require('internal/validators'); | ||
|
||
const { | ||
|
@@ -50,34 +50,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'); | ||
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); | ||
} | ||
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, | ||
|
@@ -93,30 +92,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'); | ||
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); | ||
} | ||
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]); | ||
|
@@ -136,13 +131,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); | ||
} | ||
Comment on lines
+148
to
+150
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why catch the error in the first place? Isn't returning a promise rejection strictly equivalent in an async function? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I copied and pasted from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would have been more "clean" to close that PR about adding an alias for |
||
|
||
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; | ||
|
@@ -216,7 +227,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); | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because the documentation was incorrect (or not up-to-date). It was not
roughly
equivalent, it wasstrictly
equivalent since it just wrapping it. I made that explicit.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then I guess we should document
ref
as a valid option