Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enrich stack traces with an API to add notes to a current stack frame #40331

Closed
jaredp opened this issue Oct 5, 2021 · 7 comments
Closed

Enrich stack traces with an API to add notes to a current stack frame #40331

jaredp opened this issue Oct 5, 2021 · 7 comments
Labels
diag-agenda Issues and PRs to discuss during the meetings of the diagnostics working group. errors Issues and PRs related to JavaScript errors originated in Node.js core. feature request Issues that request new features to be added to Node.js. stale

Comments

@jaredp
Copy link

jaredp commented Oct 5, 2021

Is your feature request related to a problem? Please describe.
Stack traces are a key debugging feature, but miss critical information in frame local variables. Imagine code like

async function fetchAllUrls() {
  for(const url of ["https://provider-one.example.com", "https://provider-two.example.com", "https://provider-three.example.com"]) {
    await parse(await fetch(url));
  }
}

that fails with stack trace

Error: invalid schema
    at parse (/workspace/test.js:3:14)
    at fetchAllUrls (/workspace/test.js:14:31)
    ...

it would be critical know that https://provider-two.example.com/ is broken, and not one or three. It's especially important if the failure is transient.

Describe the solution you'd like

 async function fetchAllUrls() {
   for(const url of ["https://provider-one.example.com", "https://provider-two.example.com", "https://provider-three.example.com"]) {
+    Context.addDebuggingContext(`url=${url}`);
     await parse(await fetch(url));
   }
 }

gives stack trace

Error: invalid schema
    at parse (/workspace/test.js:3:14)
    at fetchAllUrls (/workspace/test.js:14:31) [url=https://provider-two.example.com]
    ...

Describe alternatives you've considered
I currently pass an explicit Context object down the call stack from caller to callee, accumulating debugging info. When my code throws, it includes a pretty-print of the Context in the error message. This doesn't work with errors thrown by 3rd party code (npm, node builtins/internals).

We can also wrap callees with a try...catch and rethrow errors with extra annotation. There's no nice way to do this with error objects, and the try...catch is believed to have a perf impact.

@VoltrexKeyva VoltrexKeyva added errors Issues and PRs related to JavaScript errors originated in Node.js core. feature request Issues that request new features to be added to Node.js. labels Oct 5, 2021
@mhdawson
Copy link
Member

@nodejs/diagnostics FYI

@BridgeAR
Copy link
Member

@jaredp IMO the ideal way is to wrap third party libraries in try / catch and to create an own error that uses the cause part with the original error. You are able to add what ever information you want in that case as extra properties.

It is possible to keep the overhead to an absolute minimum by setting Error.stackTraceLimit to zero before creating the new error and to reset it to the former value after that. That way you'll still have the original stack trace but do not have to create a new stack trace that is not needed.

@cjihrig
Copy link
Contributor

cjihrig commented Oct 14, 2021

I currently pass an explicit Context object down the call stack from caller to callee, accumulating debugging info.

You might be able to leverage Node's async context tracking to avoid passing a context object everywhere.

I'd also take a look at https://v8.dev/docs/stack-trace-api (just note this API is V8 specific).

@tniessen
Copy link
Member

We can also wrap callees with a try...catch and rethrow errors with extra annotation. There's no nice way to do this with error objects

IMO the ideal way is to wrap third party libraries in try / catch and to create an own error that uses the cause part with the original error. You are able to add what ever information you want in that case as extra properties.

FYI, @BridgeAR is referring to https://github.com/tc39/proposal-error-cause, which addresses this use case to some degree.

I think it would be difficult for Node.js to modify stack traces beyond what JS / V8 already offer.

@mmarchini
Copy link
Contributor

That's the kind of use case where llnode thrives. Unfortunately, it's not a user friendly tool and it doesn't currently work on v14+. I also worked on a proposal for inspector protocol-based postmortem tooling in the past, but it had a huge overhead.

FWIW I'm definitely +1 on an API that allows functions to enrich their contexts on stack traces, but for it to be performant and stable it would need to be worked with V8 and probably with TC39 too. Having been part of these discussions in the past I don't have much hope for it, but I'd endorse anyone trying to move the needle in this space.

@github-actions
Copy link
Contributor

There has been no activity on this feature request for 5 months and it is unlikely to be implemented. It will be closed 6 months after the last non-automated comment.

For more information on how the project manages feature requests, please consult the feature request management document.

@github-actions
Copy link
Contributor

There has been no activity on this feature request and it is being closed. If you feel closing this issue is not the right thing to do, please leave a comment.

For more information on how the project manages feature requests, please consult the feature request management document.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
diag-agenda Issues and PRs to discuss during the meetings of the diagnostics working group. errors Issues and PRs related to JavaScript errors originated in Node.js core. feature request Issues that request new features to be added to Node.js. stale
Projects
None yet
Development

No branches or pull requests

8 participants