Skip to content

Commit 74a69ab

Browse files
devsnekBridgeAR
authored andcommitted
lib: stop using prepareStackTrace
PR-URL: #29777 Reviewed-By: Ben Coe <bencoe@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
1 parent bede981 commit 74a69ab

4 files changed

Lines changed: 65 additions & 52 deletions

File tree

‎lib/assert.js‎

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,16 @@
2323
const{ Object }=primordials;
2424

2525
const{ Buffer }=require('buffer');
26-
const{codes: {
27-
ERR_AMBIGUOUS_ARGUMENT,
28-
ERR_INVALID_ARG_TYPE,
29-
ERR_INVALID_ARG_VALUE,
30-
ERR_INVALID_RETURN_VALUE,
31-
ERR_MISSING_ARGS
32-
}}=require('internal/errors');
26+
const{
27+
codes: {
28+
ERR_AMBIGUOUS_ARGUMENT,
29+
ERR_INVALID_ARG_TYPE,
30+
ERR_INVALID_ARG_VALUE,
31+
ERR_INVALID_RETURN_VALUE,
32+
ERR_MISSING_ARGS,
33+
},
34+
overrideStackTrace,
35+
}=require('internal/errors');
3336
constAssertionError=require('internal/assert/assertion_error');
3437
const{ openSync, closeSync, readSync }=require('fs');
3538
const{ inspect }=require('internal/util/inspect');
@@ -261,10 +264,8 @@ function getErrMessage(message, fn) {
261264
Error.captureStackTrace(err,fn);
262265
Error.stackTraceLimit=tmpLimit;
263266

264-
consttmpPrepare=Error.prepareStackTrace;
265-
Error.prepareStackTrace=(_,stack)=>stack;
267+
overrideStackTrace.set(err,(_,stack)=>stack);
266268
constcall=err.stack[0];
267-
Error.prepareStackTrace=tmpPrepare;
268269

269270
constfilename=call.getFileName();
270271
constline=call.getLineNumber()-1;

‎lib/internal/errors.js‎

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,18 @@ const { kMaxLength } = internalBinding('buffer');
2121

2222
constMainContextError=Error;
2323
constErrorToString=Error.prototype.toString;
24-
// Polyfill of V8's Error.prepareStackTrace API.
25-
// https://crbug.com/v8/7848
24+
constoverrideStackTrace=newWeakMap();
2625
constprepareStackTrace=(globalThis,error,trace)=>{
26+
// API for node internals to override error stack formatting
27+
// without interfering with userland code.
28+
if(overrideStackTrace.has(error)){
29+
constf=overrideStackTrace.get(error);
30+
overrideStackTrace.delete(error);
31+
returnf(error,trace);
32+
}
33+
34+
// Polyfill of V8's Error.prepareStackTrace API.
35+
// https://crbug.com/v8/7848
2736
// `globalThis` is the global that contains the constructor which
2837
// created `error`.
2938
if(typeofglobalThis.Error.prepareStackTrace==='function'){
@@ -36,6 +45,11 @@ const prepareStackTrace = (globalThis, error, trace) => {
3645
returnMainContextError.prepareStackTrace(error,trace);
3746
}
3847

48+
// Normal error formatting:
49+
//
50+
// Error: Message
51+
// at function (file)
52+
// at file
3953
consterrorString=ErrorToString.call(error);
4054
if(trace.length===0){
4155
returnerrorString;
@@ -675,6 +689,7 @@ module.exports = {
675689
// This is exported only to facilitate testing.
676690
E,
677691
prepareStackTrace,
692+
overrideStackTrace,
678693
kEnhanceStackBeforeInspector,
679694
fatalExceptionStackEnhancers
680695
};

‎lib/internal/util.js‎

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ const {
77
ERR_NO_CRYPTO,
88
ERR_UNKNOWN_SIGNAL
99
},
10-
uvErrmapGet
10+
uvErrmapGet,
11+
overrideStackTrace,
1112
}=require('internal/errors');
1213
const{ signals }=internalBinding('constants').os;
1314
const{
@@ -338,15 +339,13 @@ function isInsideNodeModules() {
338339
// side-effect-free. Since this is currently only used for a deprecated API,
339340
// the perf implications should be okay.
340341
getStructuredStack=runInNewContext(`(function() {
341-
Error.prepareStackTrace = function(err, trace) {
342-
return trace;
343-
};
344342
Error.stackTraceLimit = Infinity;
345-
346343
return function structuredStack() {
347-
return new Error().stack;
344+
const e = new Error();
345+
overrideStackTrace.set(e, (err, trace) => trace);
346+
return e.stack;
348347
};
349-
})()`,{},{filename: 'structured-stack'});
348+
})()`,{ overrideStackTrace },{filename: 'structured-stack'});
350349
}
351350

352351
conststack=getStructuredStack();

‎lib/repl.js‎

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,15 @@ const CJSModule = require('internal/modules/cjs/loader');
6969
constdomain=require('domain');
7070
constdebug=require('internal/util/debuglog').debuglog('repl');
7171
const{
72-
ERR_CANNOT_WATCH_SIGINT,
73-
ERR_INVALID_ARG_TYPE,
74-
ERR_INVALID_REPL_EVAL_CONFIG,
75-
ERR_INVALID_REPL_INPUT,
76-
ERR_SCRIPT_EXECUTION_INTERRUPTED
77-
}=require('internal/errors').codes;
72+
codes: {
73+
ERR_CANNOT_WATCH_SIGINT,
74+
ERR_INVALID_ARG_TYPE,
75+
ERR_INVALID_REPL_EVAL_CONFIG,
76+
ERR_INVALID_REPL_INPUT,
77+
ERR_SCRIPT_EXECUTION_INTERRUPTED,
78+
},
79+
overrideStackTrace,
80+
}=require('internal/errors');
7881
const{ sendInspectorCommand }=require('internal/util/inspector');
7982
constexperimentalREPLAwait=require('internal/options').getOptionValue(
8083
'--experimental-repl-await'
@@ -473,10 +476,29 @@ function REPLServer(prompt,
473476
leterrStack='';
474477

475478
if(typeofe==='object'&&e!==null){
476-
constpstrace=Error.prepareStackTrace;
477-
Error.prepareStackTrace=prepareStackTrace(pstrace);
479+
overrideStackTrace.set(e,(error,stackFrames)=>{
480+
letframes;
481+
if(typeofstackFrames==='object'){
482+
// Search from the bottom of the call stack to
483+
// find the first frame with a null function name
484+
constidx=stackFrames
485+
.reverse()
486+
.findIndex((frame)=>frame.getFunctionName()===null);
487+
// If found, get rid of it and everything below it
488+
frames=stackFrames.splice(idx+1);
489+
}else{
490+
frames=stackFrames;
491+
}
492+
// FIXME(devsnek): this is inconsistent with the checks
493+
// that the real prepareStackTrace dispatch uses in
494+
// lib/internal/errors.js.
495+
if(typeofError.prepareStackTrace==='function'){
496+
returnError.prepareStackTrace(error,frames);
497+
}
498+
frames.push(error);
499+
returnframes.reverse().join('\n at ');
500+
});
478501
decorateErrorStack(e);
479-
Error.prepareStackTrace=pstrace;
480502

481503
if(e.domainThrown){
482504
deletee.domain;
@@ -590,30 +612,6 @@ function REPLServer(prompt,
590612
}
591613
}
592614

593-
functionfilterInternalStackFrames(structuredStack){
594-
// Search from the bottom of the call stack to
595-
// find the first frame with a null function name
596-
if(typeofstructuredStack!=='object')
597-
returnstructuredStack;
598-
constidx=structuredStack.reverse().findIndex(
599-
(frame)=>frame.getFunctionName()===null);
600-
601-
// If found, get rid of it and everything below it
602-
structuredStack=structuredStack.splice(idx+1);
603-
returnstructuredStack;
604-
}
605-
606-
functionprepareStackTrace(fn){
607-
return(error,stackFrames)=>{
608-
constframes=filterInternalStackFrames(stackFrames);
609-
if(fn){
610-
returnfn(error,frames);
611-
}
612-
frames.push(error);
613-
returnframes.reverse().join('\n at ');
614-
};
615-
}
616-
617615
function_parseREPLKeyword(keyword,rest){
618616
constcmd=this.commands[keyword];
619617
if(cmd){

0 commit comments

Comments
 (0)