I have the following reduced code:
async function fun() {
function fun1() {
return Promise.resolve(
new Promise((resolve, reject) => {
resolve();
}),
);
}
function fun0() {
return fun1().then((_) => {
return new Promise((resolve, reject) => {
console.log(new Error().stack);
});
});
}
fun0();
}
(async () => {
await fun();
})();
My goal is to obtain the complete call stack. However, the above outputs contains only the location of the anonymous Promise, but not fun0
or fun1
.
Is there a way to get the entire stack trace in v8?
Your question is slightly misguided as what you are seeing is effectively the current stack - once an asynchronous action is triggered (in your case scheduling the settlement of the Promise by calling resolve()
) synchronous execution will continue, the stack will unwind till it is eventually empty. Then at some point the asynchronous event is pushed into a task queue and eventually picked up, calling the then-handlers stored in the Promise. Thus what you are seeing is actually the stack (as in - what the V8 debugger reconstructed as a logical stack from its internal representation of the execution).
That said, V8 can actually track "async stacks" - meaning whenever an asynchronous event occurs, it stores the current stack (as some sort of string) and attaches it to the asynchronous event. Then when the event finishes and the task is picked up, it stitches together the stored stack and the asynchronous one - for more details see this related question. As this comes with quite some overhead the stack is only stored when the debugger is opened in Chrome - I guess the same can be triggered by attaching a Debugger to a running NodeJS process.