@@ -38,9 +38,12 @@ using v8::Global;
38
38
using v8::HandleScope;
39
39
using v8::Integer;
40
40
using v8::Isolate;
41
+ using v8::Just;
41
42
using v8::Local;
43
+ using v8::Maybe;
42
44
using v8::MaybeLocal;
43
45
using v8::Name;
46
+ using v8::Nothing;
44
47
using v8::Number;
45
48
using v8::Object;
46
49
using v8::ObjectTemplate;
@@ -188,6 +191,21 @@ void AsyncWrap::EmitAfter(Environment* env, double async_id) {
188
191
env->async_hooks_after_function ());
189
192
}
190
193
194
+ // TODO(addaleax): Remove once we're on C++17.
195
+ constexpr double AsyncWrap::kInvalidAsyncId ;
196
+
197
+ static Maybe<double > GetAssignedPromiseAsyncId (Environment* env,
198
+ Local<Promise> promise,
199
+ Local<Value> id_symbol) {
200
+ Local<Value> maybe_async_id;
201
+ if (!promise->Get (env->context (), id_symbol).ToLocal (&maybe_async_id)) {
202
+ return Nothing<double >();
203
+ }
204
+ return maybe_async_id->IsNumber ()
205
+ ? maybe_async_id->NumberValue (env->context ())
206
+ : Just (AsyncWrap::kInvalidAsyncId );
207
+ }
208
+
191
209
class PromiseWrap : public AsyncWrap {
192
210
public:
193
211
PromiseWrap (Environment* env, Local<Object> object, bool silent)
@@ -230,18 +248,17 @@ PromiseWrap* PromiseWrap::New(Environment* env,
230
248
231
249
// Skip for init events
232
250
if (silent) {
233
- Local<Value> maybe_async_id = promise
234
- ->Get (context, env->async_id_symbol ())
235
- .ToLocalChecked ();
236
-
237
- Local<Value> maybe_trigger_async_id = promise
238
- ->Get (context, env->trigger_async_id_symbol ())
239
- .ToLocalChecked ();
240
-
241
- if (maybe_async_id->IsNumber () && maybe_trigger_async_id->IsNumber ()) {
242
- double async_id = maybe_async_id.As <Number>()->Value ();
243
- double trigger_async_id = maybe_trigger_async_id.As <Number>()->Value ();
244
- return new PromiseWrap (env, obj, async_id, trigger_async_id);
251
+ double async_id;
252
+ double trigger_async_id;
253
+ if (!GetAssignedPromiseAsyncId (env, promise, env->async_id_symbol ())
254
+ .To (&async_id)) return nullptr ;
255
+ if (!GetAssignedPromiseAsyncId (env, promise, env->trigger_async_id_symbol ())
256
+ .To (&trigger_async_id)) return nullptr ;
257
+
258
+ if (async_id != AsyncWrap::kInvalidAsyncId &&
259
+ trigger_async_id != AsyncWrap::kInvalidAsyncId ) {
260
+ return new PromiseWrap (
261
+ env, obj, async_id, trigger_async_id);
245
262
}
246
263
}
247
264
@@ -320,46 +337,35 @@ static void FastPromiseHook(PromiseHookType type, Local<Promise> promise,
320
337
321
338
if (type == PromiseHookType::kBefore &&
322
339
env->async_hooks ()->fields ()[AsyncHooks::kBefore ] == 0 ) {
323
- Local<Value> maybe_async_id;
324
- if (!promise->Get (context, env->async_id_symbol ())
325
- .ToLocal (&maybe_async_id)) {
326
- return ;
327
- }
328
-
329
- Local<Value> maybe_trigger_async_id;
330
- if (!promise->Get (context, env->trigger_async_id_symbol ())
331
- .ToLocal (&maybe_trigger_async_id)) {
332
- return ;
333
- }
334
-
335
- if (maybe_async_id->IsNumber () && maybe_trigger_async_id->IsNumber ()) {
336
- double async_id = maybe_async_id.As <Number>()->Value ();
337
- double trigger_async_id = maybe_trigger_async_id.As <Number>()->Value ();
340
+ double async_id;
341
+ double trigger_async_id;
342
+ if (!GetAssignedPromiseAsyncId (env, promise, env->async_id_symbol ())
343
+ .To (&async_id)) return ;
344
+ if (!GetAssignedPromiseAsyncId (env, promise, env->trigger_async_id_symbol ())
345
+ .To (&trigger_async_id)) return ;
346
+
347
+ if (async_id != AsyncWrap::kInvalidAsyncId &&
348
+ trigger_async_id != AsyncWrap::kInvalidAsyncId ) {
338
349
env->async_hooks ()->push_async_context (
339
350
async_id, trigger_async_id, promise);
351
+ return ;
340
352
}
341
-
342
- return ;
343
353
}
344
354
345
355
if (type == PromiseHookType::kAfter &&
346
356
env->async_hooks ()->fields ()[AsyncHooks::kAfter ] == 0 ) {
347
- Local<Value> maybe_async_id;
348
- if (!promise->Get (context, env->async_id_symbol ())
349
- .ToLocal (&maybe_async_id)) {
350
- return ;
351
- }
357
+ double async_id;
358
+ if (!GetAssignedPromiseAsyncId (env, promise, env->async_id_symbol ())
359
+ .To (&async_id)) return ;
352
360
353
- if (maybe_async_id->IsNumber ()) {
354
- double async_id = maybe_async_id.As <Number>()->Value ();
361
+ if (async_id != AsyncWrap::kInvalidAsyncId ) {
355
362
if (env->execution_async_id () == async_id) {
356
363
// This condition might not be true if async_hooks was enabled during
357
364
// the promise callback execution.
358
365
env->async_hooks ()->pop_async_context (async_id);
359
366
}
367
+ return ;
360
368
}
361
-
362
- return ;
363
369
}
364
370
365
371
if (type == PromiseHookType::kResolve &&
0 commit comments