Skip to content

util: inspect: do not crash on an Error stack pointing to itself - #58196

Merged
nodejs-github-bot merged 3 commits into
nodejs:mainfrom
SamVerschueren:fix/inspect-cyclic-error-stack
Jun 16, 2025
Merged

util: inspect: do not crash on an Error stack pointing to itself#58196
nodejs-github-bot merged 3 commits into
nodejs:mainfrom
SamVerschueren:fix/inspect-cyclic-error-stack

Conversation

@SamVerschueren

Copy link
Copy Markdown
Contributor

See #58195

This avoids a maximum call stack size exceeded crash when the error stack is pointing to the error itself error.stack = error. This bug was introduced by #56573.

@nodejs-github-botnodejs-github-bot added needs-ci PRs that need a full CI run. util Issues and PRs related to the built-in util module. labels May 6, 2025
@SamVerschuerenSamVerschueren changed the title util: inspect: do not crash on an Error stack pointing to the error itselfutil: inspect: do not crash on an Error stack pointing to itselfMay 6, 2025
@SamVerschueren
SamVerschuerenforce-pushed the fix/inspect-cyclic-error-stack branch from 802e28b to 8b819f9CompareMay 6, 2025 16:02

@BridgeARBridgeAR left a comment

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.

LGTM. I am just surprised the regular circular detection does not pick this up. Do we know why?

The output does seem to be better in this case, so it's likely a good idea not to have the circular check trigger.
Should we maybe just add additional information that it's circular? That might be useful for users?

@SamVerschueren

SamVerschueren commented May 6, 2025

Copy link
Copy Markdown
ContributorAuthor

Open to ideas on how to show the circularity. I think it's a good idea.

@codecov

codecovBot commented May 6, 2025

Copy link
Copy Markdown

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 90.14%. Comparing base (e272637) to head (111b9ca).
Report is 327 commits behind head on main.

Additional details and impacted files
@@ Coverage Diff @@## main #58196 +/- ##
==========================================
+ Coverage 90.13% 90.14% +0.01% 
==========================================
Files 630 637 +7 Lines 186780 188028 +1248 Branches 36653 36890 +237 ==========================================
+ Hits 168347 169504 +1157 - Misses 11207 11279 +72 - Partials 7226 7245 +19 
Files with missing linesCoverage Δ
lib/internal/util/inspect.js99.96% <100.00%> (+<0.01%)⬆️

... and 185 files with indirect coverage changes

🚀 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.

@BridgeAR

Copy link
Copy Markdown
Member

@SamVerschueren instead of only returning the ErrorPrototypeToString call result, we could add additional information that the stack is circular similar to the other circular outputs.

@SamVerschueren

Copy link
Copy Markdown
ContributorAuthor

So I checked how it's done with objects where it looks like this

<ref *1> { bar: [Circular *1] }

The problem here though is that it's a method to get the stack string itself, so I don't see a way how to represent it in the same way more or less.

So I just tried some things out

in the case of the following code

constfoo=newError('foo');foo.stack=foo;console.log(foo.stack);
  1. [[Circular] Error: foo]
  2. [<Circular> Error: foo]
  3. [[Circular stack] Error: foo]
  4. [<Circular stack> Error: foo]
  5. [[Circular *stack] Error: foo]
  6. [<Circular *stack> Error: foo]

Let me know what any one of you would like to see. Or something completely different, although might be a bit more work.

<ref *1> Error: foo { stack: [Circular *1] }

But this deviates way too much from what it was I feel like.

@BridgeARBridgeAR left a comment

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.

I had a brief look into this and it does not fully fix the problem.

There are currently two spots where we miss to add adding the circular check (the other spot is for weird function names), since we have to special handle parts of the inspection before getting to the spot where we add the object to our circular check (it is intentionally at that spot to prevent doing it for e.g., empty objects, arrays, etc.).

One of them is here. Just comparing for a simple direct recursion does not prevent other cases, for example:

consterror=newError()consterror2=newError()error.stack=error2error2.stack=error

Comment threadlib/internal/util/inspect.js Outdated
@BridgeAR

Copy link
Copy Markdown
Member

@SamVerschueren could you take another look? :)

We could also land this as intermediate improvement and have another PR on top, I just thought it makes sense to combine the points that I looked at.

@SamVerschueren

Copy link
Copy Markdown
ContributorAuthor

Yes I'll definitely look into this. I was out this week so I'll probably do it over the weekend.

@BridgeAR

Copy link
Copy Markdown
Member

Ping @SamVerschueren

@SamVerschueren

Copy link
Copy Markdown
ContributorAuthor

Ugh Sorry. I totally forgot about this. I'll do it tomorrow!

@BridgeARBridgeAR left a comment

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.

LGTM, thanks for the PR!

@BridgeARBridgeAR added the request-ci Add this label to start a Jenkins CI on a PR. label Jun 13, 2025
@github-actionsgithub-actionsBot removed the request-ci Add this label to start a Jenkins CI on a PR. label Jun 13, 2025
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@Ethan-ArrowoodEthan-Arrowood left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

lgtm

Comment threadlib/internal/util/inspect.js
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@BridgeARBridgeAR added commit-queue Add this label to land a pull request using GitHub Actions. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. labels Jun 16, 2025
@nodejs-github-botnodejs-github-bot removed the commit-queue Add this label to land a pull request using GitHub Actions. label Jun 16, 2025
@nodejs-github-bot
nodejs-github-bot merged commit ea5d37e into nodejs:mainJun 16, 2025
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Landed in ea5d37e

RafaelGSS pushed a commit that referenced this pull request Jun 23, 2025
PR-URL: #58196
Reviewed-By: Jordan Harband <ljharb@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
aduh95 pushed a commit that referenced this pull request Jul 21, 2025
PR-URL: #58196
Reviewed-By: Jordan Harband <ljharb@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
aduh95 pushed a commit that referenced this pull request Jul 24, 2025
PR-URL: #58196
Reviewed-By: Jordan Harband <ljharb@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commit-queue-squashAdd this label to instruct the Commit Queue to squash all the PR commits into the first one.needs-ciPRs that need a full CI run.utilIssues and PRs related to the built-in util module.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@SamVerschueren@BridgeAR@nodejs-github-bot@ljharb@Ethan-Arrowood