-
Notifications
You must be signed in to change notification settings - Fork 29k
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
Incomplete async stack traces in Node.js 14.15.0 #36126
Comments
um, looks like it's a bug in main()
function main() {
sub();
}
async function sub() {
const err = new Error();
Error.captureStackTrace(err);
console.log('before sleep');
console.log(err.stack);
await delay(1000);
const err2 = new Error();
Error.captureStackTrace(err2);
console.log(err2.stack);
}
function delay(ms) {
return new Promise(resolve => {
setTimeout(() => resolve(), ms);
});
}
|
Maybe related to this, in dev environment I get (it doesn't matter the actual error) From previous event:
at Query.run (/app/node_modules/sequelize/lib/dialects/mysql/query.js:39:12)
at runHooks.then.then (/app/node_modules/sequelize/lib/sequelize.js:645:29)
From previous event:
at Promise.try.then.connection (/app/node_modules/sequelize/lib/sequelize.js:645:12)
From previous event:
at Promise.resolve.retry (/app/node_modules/sequelize/lib/sequelize.js:641:10) but when |
That output of |
The stack trace will be complete if you make |
class Client {
async justASimpleAsyncMethod() {
return true;
}
async connect() {
throw new Error('Connection failed');
}
}
class Manager {
async migrate() {
client = new Client();
await client.justASimpleAsyncMethod();
await client.connect();
}
}
(async () => {
const manager = new Manager();
await manager.migrate();
})(); A similar case, this bug is huge and make error tracking really hard. For the script above I can track to This is my temp solution as this is not a bug I can tolerate import Promise from 'bluebird';
global.Promise = Promise;
Promise.config({
longStackTraces: true,
}); |
For completeness, @tom10271's workaround does not work if the crash happens in 3rd party library installed via NPM. This bug really needs fixing, because it makes tracking crashes in Tensorflow.js for example very difficult. |
This is not as much a bug as it is just a limitation of the zero-cost async stack traces mechanism implemented by v8. Specifically, let's look at the original example: main()
function main() {
sub();
}
async function sub() {
console.trace('before sleep');
await delay(1000);
console.trace('after sleep');
}
function delay(ms) {
return new Promise(resolve => {
setTimeout(() => resolve(), ms);
});
} The In order for main()
async function main() {
await sub();
}
async function sub() {
console.trace('before sleep');
await delay(1000);
console.trace('after sleep');
}
function delay(ms) {
return new Promise(resolve => {
setTimeout(() => resolve(), ms);
});
} How does this change things? Well, making
The bottom line is that it absolutely is not a bug. The async stack traces mechanism is working exactly as it is designed to work -- it's just limited in what information it can capture. Now, whether that can be improved upon or not is a secondary discussion, but there is no bug in Node.js here as we are relying entirely on what v8 is providing to us here. |
Ah, so if I'm seeing broken stack traces in a library, then this is instead a bug in said library rather than Node.js. Got it - thanks for the detailed explanation @jasnell! |
Let‘s assume one wants to use “background“ promises for some async job. What‘s the correct way to do that in order to get a proper stack of something fails? |
The debate of whether this is or is not a bug is semantics, really. It depends on your POV. I understand that from the POV or a Node core developer, there isn't a bug in Node. From the POV of an application developer, a programming environment that does not fully support your ability to debug is a significant problem. I don't really care about the semantics of whether it is or isn't a bug, as long as deciding its not a bug is not used as a rationale for closing it and not addressing the issue. I really feel the issue needs to be addressed in some way, shape or form even if it means having to work around V8 limitations. |
Calling async methods from non-async methods (broken async chain) causes the sync stack trace to disappear (due to the async stack traces mechanism). Also, remove redundant function mocking (since the `traceCall` function is already mocked). See: nodejs/node#36126 (comment)
What steps will reproduce the bug?
node --async-stack-traces test.js
How often does it reproduce? Is there a required condition?
Fully reproducible
What is the expected behavior?
Based on the documentation I would assume that Node.js 14 does now support stack traces in async code but unfortunately node only generates only a partial stack trace after having used await and I would be most interested to understand why.
What do you see instead?
Additional information
The text was updated successfully, but these errors were encountered: