@@ -61,7 +61,7 @@ const active_hooks = {
61
61
// async execution. These are tracked so if the user didn't include callbacks
62
62
// for a given step, that step can bail out early.
63
63
const { kInit, kBefore, kAfter, kDestroy, kTotals, kPromiseResolve,
64
- kExecutionAsyncId, kTriggerAsyncId, kAsyncIdCounter,
64
+ kCheck , kExecutionAsyncId, kTriggerAsyncId, kAsyncIdCounter,
65
65
kInitTriggerAsyncId } = async_wrap . constants ;
66
66
67
67
// Symbols used to store the respective ids on both AsyncResource instances and
@@ -157,8 +157,10 @@ class AsyncHook {
157
157
hook_fields [ kPromiseResolve ] += + ! ! this [ promise_resolve_symbol ] ;
158
158
hooks_array . push ( this ) ;
159
159
160
- if ( prev_kTotals === 0 && hook_fields [ kTotals ] > 0 )
160
+ if ( prev_kTotals === 0 && hook_fields [ kTotals ] > 0 ) {
161
161
enablePromiseHook ( ) ;
162
+ hook_fields [ kCheck ] += 1 ;
163
+ }
162
164
163
165
return this ;
164
166
}
@@ -181,8 +183,10 @@ class AsyncHook {
181
183
hook_fields [ kPromiseResolve ] -= + ! ! this [ promise_resolve_symbol ] ;
182
184
hooks_array . splice ( index , 1 ) ;
183
185
184
- if ( prev_kTotals > 0 && hook_fields [ kTotals ] === 0 )
186
+ if ( prev_kTotals > 0 && hook_fields [ kTotals ] === 0 ) {
185
187
disablePromiseHook ( ) ;
188
+ hook_fields [ kCheck ] -= 1 ;
189
+ }
186
190
187
191
return this ;
188
192
}
@@ -244,6 +248,15 @@ function triggerAsyncId() {
244
248
return async_id_fields [ kTriggerAsyncId ] ;
245
249
}
246
250
251
+ function validateAsyncId ( asyncId , type ) {
252
+ // Skip validation when async_hooks is disabled
253
+ if ( async_hook_fields [ kCheck ] <= 0 ) return ;
254
+
255
+ if ( ! Number . isSafeInteger ( asyncId ) || asyncId < - 1 ) {
256
+ fatalError ( new errors . RangeError ( 'ERR_INVALID_ASYNC_ID' , type , asyncId ) ) ;
257
+ }
258
+ }
259
+
247
260
248
261
// Embedder API //
249
262
@@ -349,10 +362,16 @@ function setInitTriggerId(triggerAsyncId) {
349
362
350
363
351
364
function emitInitScript ( asyncId , type , triggerAsyncId , resource ) {
365
+ validateAsyncId ( asyncId , 'asyncId' ) ;
366
+ if ( triggerAsyncId !== null )
367
+ validateAsyncId ( triggerAsyncId , 'triggerAsyncId' ) ;
368
+ if ( async_hook_fields [ kCheck ] > 0 &&
369
+ ( typeof type !== 'string' || type . length <= 0 ) ) {
370
+ throw new errors . TypeError ( 'ERR_ASYNC_TYPE' , type ) ;
371
+ }
372
+
352
373
// Short circuit all checks for the common case. Which is that no hooks have
353
374
// been set. Do this to remove performance impact for embedders (and core).
354
- // Even though it bypasses all the argument checks. The performance savings
355
- // here is critical.
356
375
if ( async_hook_fields [ kInit ] === 0 )
357
376
return ;
358
377
@@ -366,18 +385,6 @@ function emitInitScript(asyncId, type, triggerAsyncId, resource) {
366
385
async_id_fields [ kInitTriggerAsyncId ] = 0 ;
367
386
}
368
387
369
- if ( ! Number . isSafeInteger ( asyncId ) || asyncId < - 1 ) {
370
- throw new errors . RangeError ( 'ERR_INVALID_ASYNC_ID' , 'asyncId' , asyncId ) ;
371
- }
372
- if ( ! Number . isSafeInteger ( triggerAsyncId ) || triggerAsyncId < - 1 ) {
373
- throw new errors . RangeError ( 'ERR_INVALID_ASYNC_ID' ,
374
- 'triggerAsyncId' ,
375
- triggerAsyncId ) ;
376
- }
377
- if ( typeof type !== 'string' || type . length <= 0 ) {
378
- throw new errors . TypeError ( 'ERR_ASYNC_TYPE' , type ) ;
379
- }
380
-
381
388
emitInitNative ( asyncId , type , triggerAsyncId , resource ) ;
382
389
}
383
390
@@ -423,15 +430,8 @@ function emitBeforeScript(asyncId, triggerAsyncId) {
423
430
// Validate the ids. An id of -1 means it was never set and is visible on the
424
431
// call graph. An id < -1 should never happen in any circumstance. Throw
425
432
// on user calls because async state should still be recoverable.
426
- if ( ! Number . isSafeInteger ( asyncId ) || asyncId < - 1 ) {
427
- fatalError (
428
- new errors . RangeError ( 'ERR_INVALID_ASYNC_ID' , 'asyncId' , asyncId ) ) ;
429
- }
430
- if ( ! Number . isSafeInteger ( triggerAsyncId ) || triggerAsyncId < - 1 ) {
431
- fatalError ( new errors . RangeError ( 'ERR_INVALID_ASYNC_ID' ,
432
- 'triggerAsyncId' ,
433
- triggerAsyncId ) ) ;
434
- }
433
+ validateAsyncId ( asyncId , 'asyncId' ) ;
434
+ validateAsyncId ( triggerAsyncId , 'triggerAsyncId' ) ;
435
435
436
436
pushAsyncIds ( asyncId , triggerAsyncId ) ;
437
437
@@ -441,10 +441,7 @@ function emitBeforeScript(asyncId, triggerAsyncId) {
441
441
442
442
443
443
function emitAfterScript ( asyncId ) {
444
- if ( ! Number . isSafeInteger ( asyncId ) || asyncId < - 1 ) {
445
- fatalError (
446
- new errors . RangeError ( 'ERR_INVALID_ASYNC_ID' , 'asyncId' , asyncId ) ) ;
447
- }
444
+ validateAsyncId ( asyncId , 'asyncId' ) ;
448
445
449
446
if ( async_hook_fields [ kAfter ] > 0 )
450
447
emitAfterNative ( asyncId ) ;
@@ -454,10 +451,7 @@ function emitAfterScript(asyncId) {
454
451
455
452
456
453
function emitDestroyScript ( asyncId ) {
457
- if ( ! Number . isSafeInteger ( asyncId ) || asyncId < - 1 ) {
458
- fatalError (
459
- new errors . RangeError ( 'ERR_INVALID_ASYNC_ID' , 'asyncId' , asyncId ) ) ;
460
- }
454
+ validateAsyncId ( asyncId , 'asyncId' ) ;
461
455
462
456
// Return early if there are no destroy callbacks, or invalid asyncId.
463
457
if ( async_hook_fields [ kDestroy ] === 0 || asyncId <= 0 )
0 commit comments