@@ -39,9 +39,12 @@ using v8::Global;
3939using v8::HandleScope;
4040using v8::Integer;
4141using v8::Isolate;
42+ using v8::Just;
4243using v8::Local;
44+ using v8::Maybe;
4345using v8::MaybeLocal;
4446using v8::Name;
47+ using v8::Nothing;
4548using v8::Number;
4649using v8::Object;
4750using v8::ObjectTemplate;
@@ -189,6 +192,21 @@ void AsyncWrap::EmitAfter(Environment* env, double async_id) {
189192 env->async_hooks_after_function ());
190193}
191194
195+ // TODO(addaleax): Remove once we're on C++17.
196+ constexpr double AsyncWrap::kInvalidAsyncId ;
197+
198+ static Maybe<double > GetAssignedPromiseAsyncId (Environment* env,
199+ Local<Promise> promise,
200+ Local<Value> id_symbol) {
201+ Local<Value> maybe_async_id;
202+ if (!promise->Get (env->context (), id_symbol).ToLocal (&maybe_async_id)) {
203+ return Nothing<double >();
204+ }
205+ return maybe_async_id->IsNumber ()
206+ ? maybe_async_id->NumberValue (env->context ())
207+ : Just (AsyncWrap::kInvalidAsyncId );
208+ }
209+
192210class PromiseWrap : public AsyncWrap {
193211 public:
194212 PromiseWrap (Environment* env, Local<Object> object, bool silent)
@@ -231,18 +249,17 @@ PromiseWrap* PromiseWrap::New(Environment* env,
231249
232250 // Skip for init events
233251 if (silent) {
234- Local<Value> maybe_async_id = promise
235- ->Get (context, env->async_id_symbol ())
236- .ToLocalChecked ();
237-
238- Local<Value> maybe_trigger_async_id = promise
239- ->Get (context, env->trigger_async_id_symbol ())
240- .ToLocalChecked ();
241-
242- if (maybe_async_id->IsNumber () && maybe_trigger_async_id->IsNumber ()) {
243- double async_id = maybe_async_id.As <Number>()->Value ();
244- double trigger_async_id = maybe_trigger_async_id.As <Number>()->Value ();
245- return new PromiseWrap (env, obj, async_id, trigger_async_id);
252+ double async_id;
253+ double trigger_async_id;
254+ if (!GetAssignedPromiseAsyncId (env, promise, env->async_id_symbol ())
255+ .To (&async_id)) return nullptr ;
256+ if (!GetAssignedPromiseAsyncId (env, promise, env->trigger_async_id_symbol ())
257+ .To (&trigger_async_id)) return nullptr ;
258+
259+ if (async_id != AsyncWrap::kInvalidAsyncId &&
260+ trigger_async_id != AsyncWrap::kInvalidAsyncId ) {
261+ return new PromiseWrap (
262+ env, obj, async_id, trigger_async_id);
246263 }
247264 }
248265
@@ -321,46 +338,35 @@ static void FastPromiseHook(PromiseHookType type, Local<Promise> promise,
321338
322339 if (type == PromiseHookType::kBefore &&
323340 env->async_hooks ()->fields ()[AsyncHooks::kBefore ] == 0 ) {
324- Local<Value> maybe_async_id;
325- if (!promise->Get (context, env->async_id_symbol ())
326- .ToLocal (&maybe_async_id)) {
327- return ;
328- }
329-
330- Local<Value> maybe_trigger_async_id;
331- if (!promise->Get (context, env->trigger_async_id_symbol ())
332- .ToLocal (&maybe_trigger_async_id)) {
333- return ;
334- }
335-
336- if (maybe_async_id->IsNumber () && maybe_trigger_async_id->IsNumber ()) {
337- double async_id = maybe_async_id.As <Number>()->Value ();
338- double trigger_async_id = maybe_trigger_async_id.As <Number>()->Value ();
341+ double async_id;
342+ double trigger_async_id;
343+ if (!GetAssignedPromiseAsyncId (env, promise, env->async_id_symbol ())
344+ .To (&async_id)) return ;
345+ if (!GetAssignedPromiseAsyncId (env, promise, env->trigger_async_id_symbol ())
346+ .To (&trigger_async_id)) return ;
347+
348+ if (async_id != AsyncWrap::kInvalidAsyncId &&
349+ trigger_async_id != AsyncWrap::kInvalidAsyncId ) {
339350 env->async_hooks ()->push_async_context (
340351 async_id, trigger_async_id, promise);
352+ return ;
341353 }
342-
343- return ;
344354 }
345355
346356 if (type == PromiseHookType::kAfter &&
347357 env->async_hooks ()->fields ()[AsyncHooks::kAfter ] == 0 ) {
348- Local<Value> maybe_async_id;
349- if (!promise->Get (context, env->async_id_symbol ())
350- .ToLocal (&maybe_async_id)) {
351- return ;
352- }
358+ double async_id;
359+ if (!GetAssignedPromiseAsyncId (env, promise, env->async_id_symbol ())
360+ .To (&async_id)) return ;
353361
354- if (maybe_async_id->IsNumber ()) {
355- double async_id = maybe_async_id.As <Number>()->Value ();
362+ if (async_id != AsyncWrap::kInvalidAsyncId ) {
356363 if (env->execution_async_id () == async_id) {
357364 // This condition might not be true if async_hooks was enabled during
358365 // the promise callback execution.
359366 env->async_hooks ()->pop_async_context (async_id);
360367 }
368+ return ;
361369 }
362-
363- return ;
364370 }
365371
366372 if (type == PromiseHookType::kResolve &&
0 commit comments