Skip to content

split err.stack so embedded stacks in err message render once#5997

Open
mostafaNazari702 wants to merge 1 commit into
mochajs:mainfrom
mostafaNazari702:duplicate-stack-message
Open

split err.stack so embedded stacks in err message render once#5997
mostafaNazari702 wants to merge 1 commit into
mochajs:mainfrom
mostafaNazari702:duplicate-stack-message

Conversation

@mostafaNazari702
Copy link
Copy Markdown
Contributor

PR Checklist

Overview

getFullErrorStack used to split err.stack by searching for err.message in it. that breaks when mocha filters stack traces and rewrites file paths, message stays unchanged but the stack changes so indexOf fails and the error gets printed twice (message + full stack).

What we do now is instead of matching the message string we now parse the stack the V8 way: treat the trailing "at ......." lines as the stack frames and everything above as the message. If the stack doesn't match V8 format we fall back to the old behavior.
We also keep err.inspect() overrides and err.cause chaining working as before.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 22, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.96%. Comparing base (6695fba) to head (9ad464b).
⚠️ Report is 10 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5997      +/-   ##
==========================================
+ Coverage   80.89%   80.96%   +0.07%     
==========================================
  Files          64       64              
  Lines        4602     4619      +17     
  Branches      976      981       +5     
==========================================
+ Hits         3723     3740      +17     
  Misses        879      879              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Member

@JoshuaKGoldberg JoshuaKGoldberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tricky stuff 😎

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Testing] This is really tricky stuff. Stack frames get surprisingly weirdly crafted in practice. A couple more test cases to add...


When the stack only contains frames:

var err = {
  message: "Error",
  stack: "    at foo (foo.js:1:1)\n    at bar (bar.js:2:2)",
  showDiff: false,
};
var test = makeTest(err);

Error output should be something like 1) test title:\n Error\n at foo (foo.js:1:1)\n at bar (bar.js:2:2).


When the embedded stack has a trailing newline, like:

var embeddedMessage =
  "An error occured with following trace:\n\nError\n    at inner (/original/foo.js:1:1)";
var stackMessage = embeddedMessage.replace(/\/original\//g, "/filtered/");
var err = {
  message: embeddedMessage,
  stack:
    "Error: " + stackMessage + "\n    at runTest (lib/runner.js:1:1)\n",
  showDiff: false,
};

The output still should smartly parse & not duplicate.

Comment thread lib/reporters/base.js
var rawStack = err.stack || message;
var lines = rawStack.split("\n");
var frameStart = lines.length;
for (var i = lines.length - 1; i >= 0; i--) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Bug] For an Error-like object with a stack containing only V8 frame lines:

{
  message: "Boom",
  stack: "    at fn (foo.js:1:1)\n    at run (foo.js:2:2)"
}

This'll make msg "".

);
});

it("should not duplicate the message when it contains an embedded stack", function () {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Testing] This passes on the original implementation:

git checkout main -- test/reporters/base.spec.js
npx mocha test/reporters/base.spec.js

The test should simulate the actual mismatch from the issue: err.message contains an embedded stack, but err.stack has the embedded stack slightly rewritten.

Comment thread lib/reporters/base.js
var stack = err.stack || message;
var index = message ? stack.indexOf(message) : -1;
var rawStack = err.stack || message;
var lines = rawStack.split("\n");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Bug] Make sure this handles a trailing \n well - we don't want the last line to be "".

@JoshuaKGoldberg JoshuaKGoldberg added the status: waiting for author waiting on response from OP or other posters - more information needed label Jun 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: waiting for author waiting on response from OP or other posters - more information needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 Bug: Reports the Error twice when its message contains something similar to a stack

2 participants