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

Exceeded the maximum call stack inside an async function leads to an uncaught promise, even if await is used properly #778

Closed
wryun opened this issue Aug 11, 2017 · 9 comments

Comments

@wryun
Copy link

wryun commented Aug 11, 2017

Running:

async function x() { 
    await x(); 
} 
(async function () { 
    try { 
        await x(); 
    } catch (e) { 
        console.log(e); 
    } 
})() 

Leads to an uncaught promise:

; node t.js
(node:434) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): RangeError: Maximum call stack size exceeded

Running the same thing with babel transpiling to bluebird coroutines works fine. I guess there are two questions?

  • is this a bug?
  • if it is a bug, should I be filing it against node or v8?
@bnoordhuis
Copy link
Member

The RangeError should bubble up to the try/catch block so yes, I would say this is a (V8) bug.

It may have been fixed upstream in V8 already but I can't test that right now and a quick code search didn't turn up anything.

@vsemozhetbyt
Copy link

In the Node.js canary with V8 6.2.172, this code still produces the same unhandled promise rejection.

@vsemozhetbyt
Copy link

vsemozhetbyt commented Aug 11, 2017

Strangely, in the Google Chrome canary with the same V8 6.2.172, it seems to bubble:

RangeError: Maximum call stack size exceeded
    at x (<anonymous>:1:1)
    at x (<anonymous>:2:11)
    at x (<anonymous>:2:11)
    at x (<anonymous>:2:11)
    at x (<anonymous>:2:11)
    at x (<anonymous>:2:11)
    at x (<anonymous>:2:11)
    at x (<anonymous>:2:11)
    at x (<anonymous>:2:11)
    at x (<anonymous>:2:11)

@wryun
Copy link
Author

wryun commented Aug 12, 2017

Sounds like I should file against Node, referencing this? (thanks @vsemozhetbyt for actually doing the investigation of Chrome behaviour against the right V8)

@bnoordhuis
Copy link
Member

I checked with V8 ToT today (nominally 6.2.218) and it works there:

$ ./out.gn/x64.release/d8 tmp/bug778.js 
RangeError: Maximum call stack size exceeded

(Yes, no stack trace - you get one if you console.log(e.stack) instead.)

I figured out what the problem is and it's a known issue: console.log() is instantiated lazily and that fails under stack overflow conditions. That is, adding a no-op console.log makes the test work:

console.log;  // Force instantiation.
async function x() { 
    await x(); 
} 
(async function () { 
    try { 
        await x(); 
    } catch (e) { 
        console.log(e); 
    } 
})() 

And that prints:

$ ./out/Release/node ../v8/tmp/bug778.js 
RangeError: Maximum call stack size exceeded
    at x (/home/bnoordhuis/src/v8/tmp/bug778.js:1:1)
    at x (/home/bnoordhuis/src/v8/tmp/bug778.js:3:11)
    # etc.

cc @addaleax - since this keeps coming up, how about we simply instantiate log(), error(), etc. eagerly in bootstrap_node.js?

@addaleax
Copy link
Member

cc @addaleax - since this keeps coming up, how about we simply instantiate log(), error(), etc. eagerly in bootstrap_node.js?

Yeah, sounds okay. ;)

@bnoordhuis
Copy link
Member

nodejs/node#14791

bnoordhuis added a commit to bnoordhuis/io.js that referenced this issue Aug 17, 2017
Before this commit they were instantiated lazily but that fails when the
first call is under stack overflow conditions.

Fixes: nodejs/help#778
@gireeshpunathil
Copy link
Member

looks like the underlying issue is resolved, close-able?
/cc @bnoordhuis

@bnoordhuis
Copy link
Member

Node.js tries to work around it on a best-effort basis. I'll close this out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants