@@ -55,6 +55,7 @@ const kTypes = [
55
55
const MainContextError = Error ;
56
56
const overrideStackTrace = new WeakMap ( ) ;
57
57
const kNoOverride = Symbol ( 'kNoOverride' ) ;
58
+ let userStackTraceLimit = Error . stackTraceLimit ;
58
59
const prepareStackTrace = ( globalThis , error , trace ) => {
59
60
// API for node internals to override error stack formatting
60
61
// without interfering with userland code.
@@ -64,6 +65,16 @@ const prepareStackTrace = (globalThis, error, trace) => {
64
65
return f ( error , trace ) ;
65
66
}
66
67
68
+ for ( let l = trace . length - 1 ; l >= 0 ; l -- ) {
69
+ const fn = trace [ l ] . getFunctionName ( ) ;
70
+ if ( fn != null && fn . startsWith ( '__node_internal_hidden_' ) ) {
71
+ trace . splice ( 0 , l + 1 ) ;
72
+ break ;
73
+ }
74
+ }
75
+ if ( trace . length > userStackTraceLimit )
76
+ trace . splice ( userStackTraceLimit ) ;
77
+
67
78
const globalOverride =
68
79
maybeOverridePrepareStackTrace ( globalThis , error , trace ) ;
69
80
if ( globalOverride !== kNoOverride ) return globalOverride ;
@@ -98,8 +109,6 @@ const maybeOverridePrepareStackTrace = (globalThis, error, trace) => {
98
109
return kNoOverride ;
99
110
} ;
100
111
101
- let excludedStackFn ;
102
-
103
112
// Lazily loaded
104
113
let util ;
105
114
let assert ;
@@ -127,6 +136,27 @@ function lazyBuffer() {
127
136
return buffer ;
128
137
}
129
138
139
+ const addCodeToName = hideStackFrames ( function ( err , name , code ) {
140
+ // Set the stack
141
+ err = captureLargerStackTrace ( err ) ;
142
+ // Add the error code to the name to include it in the stack trace.
143
+ err . name = `${ name } [${ code } ]` ;
144
+ // Access the stack to generate the error message including the error code
145
+ // from the name.
146
+ err . stack ;
147
+ // Reset the name to the actual name.
148
+ if ( name === 'SystemError' ) {
149
+ ObjectDefineProperty ( err , 'name' , {
150
+ value : name ,
151
+ enumerable : false ,
152
+ writable : true ,
153
+ configurable : true
154
+ } ) ;
155
+ } else {
156
+ delete err . name ;
157
+ }
158
+ } ) ;
159
+
130
160
// A specialized Error that includes an additional info property with
131
161
// additional information about the error condition.
132
162
// It has the properties present in a UVException but with a custom error
@@ -137,18 +167,14 @@ function lazyBuffer() {
137
167
// and may have .path and .dest.
138
168
class SystemError extends Error {
139
169
constructor ( key , context ) {
140
- if ( excludedStackFn === undefined ) {
141
- super ( ) ;
142
- } else {
143
- const limit = Error . stackTraceLimit ;
144
- Error . stackTraceLimit = 0 ;
145
- super ( ) ;
146
- // Reset the limit and setting the name property.
147
- Error . stackTraceLimit = limit ;
148
- }
170
+ const limit = Error . stackTraceLimit ;
171
+ Error . stackTraceLimit = 0 ;
172
+ super ( ) ;
173
+ // Reset the limit and setting the name property.
174
+ Error . stackTraceLimit = limit ;
149
175
const prefix = getMessage ( key , [ ] , this ) ;
150
176
let message = `${ prefix } : ${ context . syscall } returned ` +
151
- `${ context . code } (${ context . message } )` ;
177
+ `${ context . code } (${ context . message } )` ;
152
178
153
179
if ( context . path !== undefined )
154
180
message += ` ${ context . path } ` ;
@@ -253,16 +279,11 @@ function makeSystemErrorWithCode(key) {
253
279
254
280
function makeNodeErrorWithCode ( Base , key ) {
255
281
return function NodeError ( ...args ) {
256
- let error ;
257
- if ( excludedStackFn === undefined ) {
258
- error = new Base ( ) ;
259
- } else {
260
- const limit = Error . stackTraceLimit ;
261
- Error . stackTraceLimit = 0 ;
262
- error = new Base ( ) ;
263
- // Reset the limit and setting the name property.
264
- Error . stackTraceLimit = limit ;
265
- }
282
+ const limit = Error . stackTraceLimit ;
283
+ Error . stackTraceLimit = 0 ;
284
+ const error = new Base ( ) ;
285
+ // Reset the limit and setting the name property.
286
+ Error . stackTraceLimit = limit ;
266
287
const message = getMessage ( key , args , error ) ;
267
288
ObjectDefineProperty ( error , 'message' , {
268
289
value : message ,
@@ -286,45 +307,9 @@ function makeNodeErrorWithCode(Base, key) {
286
307
287
308
// This function removes unnecessary frames from Node.js core errors.
288
309
function hideStackFrames ( fn ) {
289
- return function hidden ( ...args ) {
290
- // Make sure the most outer `hideStackFrames()` function is used.
291
- let setStackFn = false ;
292
- if ( excludedStackFn === undefined ) {
293
- excludedStackFn = hidden ;
294
- setStackFn = true ;
295
- }
296
- try {
297
- return fn ( ...args ) ;
298
- } finally {
299
- if ( setStackFn === true ) {
300
- excludedStackFn = undefined ;
301
- }
302
- }
303
- } ;
304
- }
305
-
306
- function addCodeToName ( err , name , code ) {
307
- // Set the stack
308
- if ( excludedStackFn !== undefined ) {
309
- // eslint-disable-next-line no-restricted-syntax
310
- Error . captureStackTrace ( err , excludedStackFn ) ;
311
- }
312
- // Add the error code to the name to include it in the stack trace.
313
- err . name = `${ name } [${ code } ]` ;
314
- // Access the stack to generate the error message including the error code
315
- // from the name.
316
- err . stack ;
317
- // Reset the name to the actual name.
318
- if ( name === 'SystemError' ) {
319
- ObjectDefineProperty ( err , 'name' , {
320
- value : name ,
321
- enumerable : false ,
322
- writable : true ,
323
- configurable : true
324
- } ) ;
325
- } else {
326
- delete err . name ;
327
- }
310
+ const hidden = '__node_internal_hidden_' + fn . name ;
311
+ ObjectDefineProperty ( fn , 'name' , { value : hidden } ) ;
312
+ return fn ;
328
313
}
329
314
330
315
// Utility function for registering the error codes. Only used here. Exported
@@ -393,6 +378,16 @@ function uvErrmapGet(name) {
393
378
return uvBinding . errmap . get ( name ) ;
394
379
}
395
380
381
+ function captureLargerStackTrace ( err ) {
382
+ userStackTraceLimit = Error . stackTraceLimit ;
383
+ Error . stackTraceLimit = 20 ;
384
+ // eslint-disable-next-line no-restricted-syntax
385
+ Error . captureStackTrace ( err ) ;
386
+ // Reset the limit and setting the name property.
387
+ Error . stackTraceLimit = userStackTraceLimit ;
388
+
389
+ return err ;
390
+ }
396
391
397
392
/**
398
393
* This creates an error compatible with errors produced in the C++
@@ -403,8 +398,8 @@ function uvErrmapGet(name) {
403
398
* @param {Object } ctx
404
399
* @returns {Error }
405
400
*/
406
- function uvException ( ctx ) {
407
- const [ code , uvmsg ] = uvErrmapGet ( ctx . errno ) || uvUnmappedError ;
401
+ const uvException = hideStackFrames ( function ( ctx ) {
402
+ const [ code , uvmsg ] = uvErrmapGet ( ctx . errno ) || uvUnmappedError ;
408
403
let message = `${ code } : ${ ctx . message || uvmsg } , ${ ctx . syscall } ` ;
409
404
410
405
let path ;
@@ -444,10 +439,8 @@ function uvException(ctx) {
444
439
err . dest = dest ;
445
440
}
446
441
447
- // eslint-disable-next-line no-restricted-syntax
448
- Error . captureStackTrace ( err , excludedStackFn || uvException ) ;
449
- return err ;
450
- }
442
+ return captureLargerStackTrace ( err ) ;
443
+ } ) ;
451
444
452
445
/**
453
446
* This creates an error compatible with errors produced in the C++
@@ -460,37 +453,37 @@ function uvException(ctx) {
460
453
* @param {number } [port]
461
454
* @returns {Error }
462
455
*/
463
- function uvExceptionWithHostPort ( err , syscall , address , port ) {
464
- const [ code , uvmsg ] = uvErrmapGet ( err ) || uvUnmappedError ;
465
- const message = `${ syscall } ${ code } : ${ uvmsg } ` ;
466
- let details = '' ;
467
-
468
- if ( port && port > 0 ) {
469
- details = ` ${ address } :${ port } ` ;
470
- } else if ( address ) {
471
- details = ` ${ address } ` ;
472
- }
456
+ const uvExceptionWithHostPort =
457
+ hideStackFrames ( function ( err , syscall , address , port ) {
458
+ const [ code , uvmsg ] = uvErrmapGet ( err ) || uvUnmappedError ;
459
+ const message = `${ syscall } ${ code } : ${ uvmsg } ` ;
460
+ let details = '' ;
461
+
462
+ if ( port && port > 0 ) {
463
+ details = ` ${ address } :${ port } ` ;
464
+ } else if ( address ) {
465
+ details = ` ${ address } ` ;
466
+ }
473
467
474
- // Reducing the limit improves the performance significantly. We do not loose
475
- // the stack frames due to the `captureStackTrace()` function that is called
476
- // later.
477
- const tmpLimit = Error . stackTraceLimit ;
478
- Error . stackTraceLimit = 0 ;
479
- // eslint-disable-next-line no-restricted-syntax
480
- const ex = new Error ( `${ message } ${ details } ` ) ;
481
- Error . stackTraceLimit = tmpLimit ;
482
- ex . code = code ;
483
- ex . errno = err ;
484
- ex . syscall = syscall ;
485
- ex . address = address ;
486
- if ( port ) {
487
- ex . port = port ;
488
- }
468
+ // Reducing the limit improves the performance significantly. We do not
469
+ // loose the stack frames due to the `captureStackTrace()` function that
470
+ // is called later.
471
+ const tmpLimit = Error . stackTraceLimit ;
472
+ Error . stackTraceLimit = 0 ;
473
+ // eslint-disable-next-line no-restricted-syntax
474
+ const ex = new Error ( `${ message } ${ details } ` ) ;
475
+ Error . stackTraceLimit = tmpLimit ;
476
+ ex . code = code ;
477
+ ex . errno = err ;
478
+ ex . syscall = syscall ;
479
+ ex . address = address ;
480
+ if ( port ) {
481
+ ex . port = port ;
482
+ }
489
483
490
- // eslint-disable-next-line no-restricted-syntax
491
- Error . captureStackTrace ( ex , excludedStackFn || uvExceptionWithHostPort ) ;
492
- return ex ;
493
- }
484
+ captureLargerStackTrace ( ex ) ;
485
+ return ex ;
486
+ } ) ;
494
487
495
488
/**
496
489
* This used to be util._errnoException().
@@ -500,7 +493,7 @@ function uvExceptionWithHostPort(err, syscall, address, port) {
500
493
* @param {string } [original]
501
494
* @returns {Error }
502
495
*/
503
- function errnoException ( err , syscall , original ) {
496
+ const errnoException = hideStackFrames ( function ( err , syscall , original ) {
504
497
// TODO(joyeecheung): We have to use the type-checked
505
498
// getSystemErrorName(err) to guard against invalid arguments from users.
506
499
// This can be replaced with [ code ] = errmap.get(err) when this method
@@ -510,16 +503,18 @@ function errnoException(err, syscall, original) {
510
503
const message = original ?
511
504
`${ syscall } ${ code } ${ original } ` : `${ syscall } ${ code } ` ;
512
505
506
+ const tmpLimit = Error . stackTraceLimit ;
507
+ Error . stackTraceLimit = 0 ;
513
508
// eslint-disable-next-line no-restricted-syntax
514
509
const ex = new Error ( message ) ;
510
+ Error . stackTraceLimit = tmpLimit ;
515
511
ex . errno = err ;
516
512
ex . code = code ;
517
513
ex . syscall = syscall ;
518
514
519
- // eslint-disable-next-line no-restricted-syntax
520
- Error . captureStackTrace ( ex , excludedStackFn || errnoException ) ;
515
+ captureLargerStackTrace ( ex ) ;
521
516
return ex ;
522
- }
517
+ } ) ;
523
518
524
519
/**
525
520
* Deprecated, new function is `uvExceptionWithHostPort()`
@@ -532,51 +527,50 @@ function errnoException(err, syscall, original) {
532
527
* @param {string } [additional]
533
528
* @returns {Error }
534
529
*/
535
- function exceptionWithHostPort ( err , syscall , address , port , additional ) {
536
- // TODO(joyeecheung): We have to use the type-checked
537
- // getSystemErrorName(err) to guard against invalid arguments from users.
538
- // This can be replaced with [ code ] = errmap.get(err) when this method
539
- // is no longer exposed to user land.
540
- if ( util === undefined ) util = require ( 'util' ) ;
541
- const code = util . getSystemErrorName ( err ) ;
542
- let details = '' ;
543
- if ( port && port > 0 ) {
544
- details = ` ${ address } :${ port } ` ;
545
- } else if ( address ) {
546
- details = ` ${ address } ` ;
547
- }
548
- if ( additional ) {
549
- details += ` - Local (${ additional } )` ;
550
- }
530
+ const exceptionWithHostPort =
531
+ hideStackFrames ( function ( err , syscall , address , port , additional ) {
532
+ // TODO(joyeecheung): We have to use the type-checked
533
+ // getSystemErrorName(err) to guard against invalid arguments from users.
534
+ // This can be replaced with [ code ] = errmap.get(err) when this method
535
+ // is no longer exposed to user land.
536
+ if ( util === undefined ) util = require ( 'util' ) ;
537
+ const code = util . getSystemErrorName ( err ) ;
538
+ let details = '' ;
539
+ if ( port && port > 0 ) {
540
+ details = ` ${ address } :${ port } ` ;
541
+ } else if ( address ) {
542
+ details = ` ${ address } ` ;
543
+ }
544
+ if ( additional ) {
545
+ details += ` - Local (${ additional } )` ;
546
+ }
551
547
552
- // Reducing the limit improves the performance significantly. We do not loose
553
- // the stack frames due to the `captureStackTrace()` function that is called
554
- // later.
555
- const tmpLimit = Error . stackTraceLimit ;
556
- Error . stackTraceLimit = 0 ;
557
- // eslint-disable-next-line no-restricted-syntax
558
- const ex = new Error ( `${ syscall } ${ code } ${ details } ` ) ;
559
- Error . stackTraceLimit = tmpLimit ;
560
- ex . errno = err ;
561
- ex . code = code ;
562
- ex . syscall = syscall ;
563
- ex . address = address ;
564
- if ( port ) {
565
- ex . port = port ;
566
- }
548
+ // Reducing the limit improves the performance significantly. We do not
549
+ // loose the stack frames due to the `captureStackTrace()` function that
550
+ // is called later.
551
+ const tmpLimit = Error . stackTraceLimit ;
552
+ Error . stackTraceLimit = 0 ;
553
+ // eslint-disable-next-line no-restricted-syntax
554
+ const ex = new Error ( `${ syscall } ${ code } ${ details } ` ) ;
555
+ Error . stackTraceLimit = tmpLimit ;
556
+ ex . errno = err ;
557
+ ex . code = code ;
558
+ ex . syscall = syscall ;
559
+ ex . address = address ;
560
+ if ( port ) {
561
+ ex . port = port ;
562
+ }
567
563
568
- // eslint-disable-next-line no-restricted-syntax
569
- Error . captureStackTrace ( ex , excludedStackFn || exceptionWithHostPort ) ;
570
- return ex ;
571
- }
564
+ return captureLargerStackTrace ( ex ) ;
565
+ } ) ;
572
566
573
567
/**
574
568
* @param {number|string } code - A libuv error number or a c-ares error code
575
569
* @param {string } syscall
576
570
* @param {string } [hostname]
577
571
* @returns {Error }
578
572
*/
579
- function dnsException ( code , syscall , hostname ) {
573
+ const dnsException = hideStackFrames ( function ( code , syscall , hostname ) {
580
574
let errno ;
581
575
// If `code` is of type number, it is a libuv error number, else it is a
582
576
// c-ares error code.
@@ -611,10 +605,8 @@ function dnsException(code, syscall, hostname) {
611
605
ex . hostname = hostname ;
612
606
}
613
607
614
- // eslint-disable-next-line no-restricted-syntax
615
- Error . captureStackTrace ( ex , excludedStackFn || dnsException ) ;
616
- return ex ;
617
- }
608
+ return captureLargerStackTrace ( ex ) ;
609
+ } ) ;
618
610
619
611
function connResetException ( msg ) {
620
612
// eslint-disable-next-line no-restricted-syntax
0 commit comments