summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/node/lib.rs10
-rw-r--r--ext/node/polyfills/async_hooks.ts20
2 files changed, 19 insertions, 11 deletions
diff --git a/ext/node/lib.rs b/ext/node/lib.rs
index 6d496f001..a623eac11 100644
--- a/ext/node/lib.rs
+++ b/ext/node/lib.rs
@@ -138,6 +138,15 @@ fn op_is_any_arraybuffer(value: serde_v8::Value) -> bool {
value.v8_value.is_array_buffer() || value.v8_value.is_shared_array_buffer()
}
+#[op(fast)]
+fn op_node_is_promise_rejected(value: serde_v8::Value) -> bool {
+ let Ok(promise) = v8::Local::<v8::Promise>::try_from(value.v8_value) else {
+ return false;
+ };
+
+ promise.state() == v8::PromiseState::Rejected
+}
+
deno_core::extension!(deno_node,
deps = [ deno_io, deno_fs ],
parameters = [P: NodePermissions],
@@ -233,6 +242,7 @@ deno_core::extension!(deno_node,
ops::http::op_node_http_request<P>,
op_node_build_os,
op_is_any_arraybuffer,
+ op_node_is_promise_rejected,
ops::require::op_require_init_paths,
ops::require::op_require_node_module_paths<P>,
ops::require::op_require_proxy_path,
diff --git a/ext/node/polyfills/async_hooks.ts b/ext/node/polyfills/async_hooks.ts
index df42847a2..c97e81ef5 100644
--- a/ext/node/polyfills/async_hooks.ts
+++ b/ext/node/polyfills/async_hooks.ts
@@ -10,6 +10,7 @@
import { validateFunction } from "ext:deno_node/internal/validators.mjs";
const { core } = globalThis.__bootstrap;
+const { ops } = core;
function assert(cond: boolean) {
if (!cond) throw new Error("Assertion failed");
@@ -29,10 +30,6 @@ let rootAsyncFrame: AsyncContextFrame | undefined = undefined;
let promiseHooksSet = false;
const asyncContext = Symbol("asyncContext");
-function isRejected(promise: Promise<unknown>) {
- const [state] = core.getPromiseDetails(promise);
- return state == 2;
-}
function setPromiseHooks() {
if (promiseHooksSet) {
@@ -43,12 +40,14 @@ function setPromiseHooks() {
const init = (promise: Promise<unknown>) => {
const currentFrame = AsyncContextFrame.current();
if (!currentFrame.isRoot()) {
- assert(AsyncContextFrame.tryGetContext(promise) == null);
+ if (typeof promise[asyncContext] !== "undefined") {
+ throw new Error("Promise already has async context");
+ }
AsyncContextFrame.attachContext(promise);
}
};
const before = (promise: Promise<unknown>) => {
- const maybeFrame = AsyncContextFrame.tryGetContext(promise);
+ const maybeFrame = promise[asyncContext];
if (maybeFrame) {
pushAsyncFrame(maybeFrame);
} else {
@@ -57,16 +56,16 @@ function setPromiseHooks() {
};
const after = (promise: Promise<unknown>) => {
popAsyncFrame();
- if (!isRejected(promise)) {
+ if (!ops.op_node_is_promise_rejected(promise)) {
// @ts-ignore promise async context
- delete promise[asyncContext];
+ promise[asyncContext] = undefined;
}
};
const resolve = (promise: Promise<unknown>) => {
const currentFrame = AsyncContextFrame.current();
if (
- !currentFrame.isRoot() && isRejected(promise) &&
- AsyncContextFrame.tryGetContext(promise) == null
+ !currentFrame.isRoot() && ops.op_node_is_promise_rejected(promise) &&
+ typeof promise[asyncContext] === "undefined"
) {
AsyncContextFrame.attachContext(promise);
}
@@ -117,7 +116,6 @@ class AsyncContextFrame {
}
static attachContext(promise: Promise<unknown>) {
- assert(!(asyncContext in promise));
// @ts-ignore promise async context
promise[asyncContext] = AsyncContextFrame.current();
}