Skip to content

Commit 3310095

Browse files
legendecasRafaelGSS
authored andcommitted
repl: fix prepareStackTrace frames array order
The second parameter of `Error.prepareStackTrace` is an array of reversed call site frames. PR-URL: #50827 Fixes: #50733 Reviewed-By: Ethan Arrowood <ethan@arrowood.dev> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
1 parent 7e98349 commit 3310095

File tree

2 files changed

+22
-16
lines changed

2 files changed

+22
-16
lines changed

lib/repl.js

+12-14
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,21 @@
4545
const {
4646
ArrayPrototypeAt,
4747
ArrayPrototypeFilter,
48-
ArrayPrototypeFindIndex,
48+
ArrayPrototypeFindLastIndex,
4949
ArrayPrototypeForEach,
5050
ArrayPrototypeIncludes,
5151
ArrayPrototypeJoin,
5252
ArrayPrototypeMap,
5353
ArrayPrototypePop,
5454
ArrayPrototypePush,
5555
ArrayPrototypePushApply,
56-
ArrayPrototypeReverse,
5756
ArrayPrototypeShift,
5857
ArrayPrototypeSlice,
5958
ArrayPrototypeSome,
6059
ArrayPrototypeSort,
61-
ArrayPrototypeSplice,
6260
ArrayPrototypeUnshift,
6361
Boolean,
64-
Error,
62+
Error: MainContextError,
6563
FunctionPrototypeBind,
6664
JSONStringify,
6765
MathMaxApply,
@@ -630,10 +628,10 @@ function REPLServer(prompt,
630628
if (self.breakEvalOnSigint) {
631629
const interrupt = new Promise((resolve, reject) => {
632630
sigintListener = () => {
633-
const tmp = Error.stackTraceLimit;
634-
if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0;
631+
const tmp = MainContextError.stackTraceLimit;
632+
if (isErrorStackTraceLimitWritable()) MainContextError.stackTraceLimit = 0;
635633
const err = new ERR_SCRIPT_EXECUTION_INTERRUPTED();
636-
if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = tmp;
634+
if (isErrorStackTraceLimitWritable()) MainContextError.stackTraceLimit = tmp;
637635
reject(err);
638636
};
639637
prioritizedSigintQueue.add(sigintListener);
@@ -679,23 +677,23 @@ function REPLServer(prompt,
679677
if (typeof stackFrames === 'object') {
680678
// Search from the bottom of the call stack to
681679
// find the first frame with a null function name
682-
const idx = ArrayPrototypeFindIndex(
683-
ArrayPrototypeReverse(stackFrames),
680+
const idx = ArrayPrototypeFindLastIndex(
681+
stackFrames,
684682
(frame) => frame.getFunctionName() === null,
685683
);
686684
// If found, get rid of it and everything below it
687-
frames = ArrayPrototypeSplice(stackFrames, idx + 1);
685+
frames = ArrayPrototypeSlice(stackFrames, 0, idx);
688686
} else {
689687
frames = stackFrames;
690688
}
691689
// FIXME(devsnek): this is inconsistent with the checks
692690
// that the real prepareStackTrace dispatch uses in
693691
// lib/internal/errors.js.
694-
if (typeof Error.prepareStackTrace === 'function') {
695-
return Error.prepareStackTrace(error, frames);
692+
if (typeof MainContextError.prepareStackTrace === 'function') {
693+
return MainContextError.prepareStackTrace(error, frames);
696694
}
697-
ArrayPrototypePush(frames, error);
698-
return ArrayPrototypeJoin(ArrayPrototypeReverse(frames), '\n at ');
695+
ArrayPrototypeUnshift(frames, error);
696+
return ArrayPrototypeJoin(frames, '\n at ');
699697
});
700698
decorateErrorStack(e);
701699

test/parallel/test-repl-pretty-custom-stack.js

+10-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,9 @@ const origPrepareStackTrace = Error.prepareStackTrace;
4242
Error.prepareStackTrace = (err, stack) => {
4343
if (err instanceof SyntaxError)
4444
return err.toString();
45-
stack.push(err);
46-
return stack.reverse().join('--->\n');
45+
// Insert the error at the beginning of the stack
46+
stack.unshift(err);
47+
return stack.join('--->\n');
4748
};
4849

4950
process.on('uncaughtException', (e) => {
@@ -78,3 +79,10 @@ const tests = [
7879
];
7980

8081
tests.forEach(run);
82+
83+
// Verify that the stack can be generated when Error.prepareStackTrace is deleted.
84+
delete Error.prepareStackTrace;
85+
run({
86+
command: 'throw new TypeError(\'Whoops!\')',
87+
expected: 'Uncaught TypeError: Whoops!\n'
88+
});

0 commit comments

Comments
 (0)