Using the following snippet, promiseStateAsync
will swallow unhandled rejections if the promise is rejected after being inspected by promiseStateAsync
const marker = Symbol("marker");
async function promiseStateAsync(promise) {
if (!(typeof promise === "object" && typeof promise.then === "function")) {
throw new TypeError(`Expected a promise, got ${typeof promise}`);
}
// Ensure unhandled rejections don't get swallowed.
await new Promise((resolve) => {
if (typeof setImmediate === "function") {
setImmediate(resolve);
} else {
setTimeout(resolve);
}
});
try {
return (await Promise.race([promise, marker])) === marker
? "pending"
: "fulfilled";
} catch {
return "rejected";
}
}
let reject;
let promise = new Promise((_res, rej) => {
reject = rej;
});
const promiseState = await promiseStateAsync(promise);
console.log(promiseState);
setTimeout(() => {
reject("dinosaur");
console.log("the setTimeout triggered");
}, 1000);
Note: in the browser I used the following events to check if the unhandled rejection event is raised, which it wasn't:
window.addEventListener("unhandledrejection", (ev) => {
console.warn(`UNHANDLED PROMISE REJECTION: ${ev.reason}`);
});
window.addEventListener('error', (ev) => {
console.warn(`UNHANDLED ERROR: ${ev.reason}`);
});
This behavior is seen in both Node and browsers
I have tested it on the following platforms:
Win11 Chrome Version 122.0.6261.129
Win11 Firefox Version 123.0.1
macOS Sonoma 14.4 Chrome Version 122.0.6261.129
macOS Sonoma 14.4 Firefox Version 123.0.1
macOS Sonoma 14.4 Safari Version 17.4 (19618.1.15.11.12)
Node versions v18.16.1 and v20.11.0 on both Win11 and macOS Sonoma 14.4
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too