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

Wrong async stack trace #30822

Closed
ZFail opened this issue Dec 6, 2019 · 7 comments
Closed

Wrong async stack trace #30822

ZFail opened this issue Dec 6, 2019 · 7 comments
Labels
v8 engine Issues and PRs related to the V8 dependency.

Comments

@ZFail
Copy link

ZFail commented Dec 6, 2019

Version: v13.3.0
Platform: Windows 7x64 and Ununtu 18.04 Linux 4.15.0-70-generic #79-Ubuntu SMP Tue Nov 12 10:36:11 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

This fragment of code:

const fs = require('fs')

async function bar() {
    // throw new Error('Good stack trace')
    try {
        await fs.promises.readFile('nonexistent-file')
    } catch (e) {
        throw new Error('Wrong stack trace')
    }
}

async function run() {
    await new Promise(resolve => setTimeout(resolve, 10))
    await bar()
}

run().then(() => console.log('success'), error => console.error(error))

generates wrong stack trace:

Error: Wrong stack trace
    at bar (D:\projects\test-exc\exc.js:8:15)

If we replace try-catch block with simple throw new Error('Good stack trace'), stack trace will be normal:

Error: Good stack trace
    at bar (D:\projects\test-exc\exc.js:4:11)
    at run (D:\projects\test-exc\exc.js:14:11)
@BridgeAR
Copy link
Member

BridgeAR commented Dec 6, 2019

@nodejs/v8 this seems to an issue with V8 and I am able to reproduce it in the dev tools as well.

Simplified test case (without anything Node.js specific):

async function bar() {
    // throw new Error('Good stack trace')
    try {
        await Promise.reject(new Error('Good stack trace'))
    } catch (e) {
        console.log(e)
        throw new Error('Wrong stack trace')
    }
}

async function run() {
    await bar()
}

run().then(() => console.log('success'), error => console.error(error))

@BridgeAR BridgeAR added the v8 engine Issues and PRs related to the V8 dependency. label Dec 6, 2019
@ryzokuken
Copy link
Contributor

@BridgeAR could you please file this issue upstream?

@verwaest
Copy link
Contributor

@BridgeAR
Copy link
Member

@verwaest I also opened an issue for it on the V8 issue tracker a couple of days ago: https://bugs.chromium.org/p/v8/issues/detail?id=10040

pull bot pushed a commit to p-g-krish/v8 that referenced this issue Jan 10, 2020
Also capture async stack traces if we're in a reject handler.

Fixes node issue nodejs/node#30822

Change-Id: I703012ddb88b5b5d17baba843a969b398ef99fa1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1969897
Auto-Submit: Toon Verwaest <[email protected]>
Reviewed-by: Benedikt Meurer <[email protected]>
Commit-Queue: Toon Verwaest <[email protected]>
Cr-Commit-Position: refs/heads/master@{#65687}
@niyarlatotep
Copy link

niyarlatotep commented Jan 17, 2020

@BridgeAR could you please have a look?
I have a similar problem, is it the same? Or is it a different problem?
Good stack trace (one iteration only):

(async function() {
    try {
        await foo();
    } catch (e) {
        console.error(e);
    }
})();

async function foo(){
    let exception;
    for (let i=0; i<1; i++){
        try {
            await Promise.reject(new Error('Good stack trace'));
        } catch (e) {
            exception = e;
        }
    }
    throw exception;
}

Bad stack trace (if two iterations and more):

(async function() {
    try {
        await foo();
    } catch (e) {
        console.error(e);
    }
})();

async function foo(){
    let exception;
    for (let i=0; i<=1; i++){
        try {
            await Promise.reject(new Error('Bad stack trace'));
        } catch (e) {
            exception = e;
        }
    }
    throw exception;
}

@verwaest
Copy link
Contributor

That's basically the same. The first iteration (after my fix) you still get a complete stack trace because you're still executing synchronously when the error object is created. The await isn't executed yet. Any iteration after that now includes the first (anonymous) function, where it didn't before the fix.

@targos
Copy link
Member

targos commented Nov 20, 2021

Fixed in V8.

@targos targos closed this as completed Nov 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
v8 engine Issues and PRs related to the V8 dependency.
Projects
None yet
Development

No branches or pull requests

6 participants