node:timers fixes (#16855)

This commit is contained in:
190n
2025-02-26 16:45:02 -08:00
committed by GitHub
parent baca1f4634
commit b3edef5989
54 changed files with 2669 additions and 355 deletions

View File

@@ -1,7 +1,7 @@
// Hardcoded module "node:timers/promises"
// https://github.com/niksy/isomorphic-timers-promises/blob/master/index.js
const { validateBoolean, validateAbortSignal, validateObject } = require("internal/validators");
const { validateBoolean, validateAbortSignal, validateObject, validateNumber } = require("internal/validators");
const symbolAsyncIterator = Symbol.asyncIterator;
@@ -22,6 +22,16 @@ function asyncIterator({ next: nextFunction, return: returnFunction }) {
function setTimeoutPromise(after = 1, value, options = {}) {
const arguments_ = [].concat(value ?? []);
try {
// If after is a number, but an invalid one (too big, Infinity, NaN), we only want to emit a
// warning, not throw an error. So we can't call validateNumber as that will throw if the number
// is outside of a given range.
if (typeof after != "number") {
validateNumber(after, "delay");
}
} catch (error) {
return Promise.reject(error);
}
try {
validateObject(options, "options");
} catch (error) {
@@ -39,7 +49,7 @@ function setTimeoutPromise(after = 1, value, options = {}) {
return Promise.reject(error);
}
if (signal?.aborted) {
return Promise.reject($makeAbortError());
return Promise.reject($makeAbortError(undefined, { cause: signal.reason }));
}
let onCancel;
const returnValue = new Promise((resolve, reject) => {
@@ -50,7 +60,7 @@ function setTimeoutPromise(after = 1, value, options = {}) {
if (signal) {
onCancel = () => {
clearTimeout(timeout);
reject($makeAbortError());
reject($makeAbortError(undefined, { cause: signal.reason }));
};
signal.addEventListener("abort", onCancel);
}
@@ -78,7 +88,7 @@ function setImmediatePromise(value, options = {}) {
return Promise.reject(error);
}
if (signal?.aborted) {
return Promise.reject($makeAbortError());
return Promise.reject($makeAbortError(undefined, { cause: signal.reason }));
}
let onCancel;
const returnValue = new Promise((resolve, reject) => {
@@ -89,7 +99,7 @@ function setImmediatePromise(value, options = {}) {
if (signal) {
onCancel = () => {
clearImmediate(immediate);
reject($makeAbortError());
reject($makeAbortError(undefined, { cause: signal.reason }));
};
signal.addEventListener("abort", onCancel);
}
@@ -101,6 +111,20 @@ function setImmediatePromise(value, options = {}) {
function setIntervalPromise(after = 1, value, options = {}) {
/* eslint-disable no-undefined, no-unreachable-loop, no-loop-func */
try {
// If after is a number, but an invalid one (too big, Infinity, NaN), we only want to emit a
// warning, not throw an error. So we can't call validateNumber as that will throw if the number
// is outside of a given range.
if (typeof after != "number") {
validateNumber(after, "delay");
}
} catch (error) {
return asyncIterator({
next: function () {
return Promise.reject(error);
},
});
}
try {
validateObject(options, "options");
} catch (error) {
@@ -132,7 +156,7 @@ function setIntervalPromise(after = 1, value, options = {}) {
if (signal?.aborted) {
return asyncIterator({
next: function () {
return Promise.reject($makeAbortError());
return Promise.reject($makeAbortError(undefined, { cause: signal.reason }));
},
});
}
@@ -173,7 +197,7 @@ function setIntervalPromise(after = 1, value, options = {}) {
resolve();
}
} else if (notYielded === 0) {
reject($makeAbortError());
reject($makeAbortError(undefined, { cause: signal.reason }));
} else {
resolve();
}
@@ -181,6 +205,8 @@ function setIntervalPromise(after = 1, value, options = {}) {
if (notYielded > 0) {
notYielded = notYielded - 1;
return { done: false, value: value };
} else if (signal?.aborted) {
throw $makeAbortError(undefined, { cause: signal.reason });
}
return { done: true };
});