You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
REPL: await in curly braces {} gives unexpected and unhelpful errors unless something is outside braces too #46196
> {let three = 3; await Promise.resolve();}
({let three = 3; await Promise.resolve();})
^^^^^
Uncaught SyntaxError: Unexpected identifier
> {{await Promise.resolve();}; six = 6;}
({{await Promise.resolve();}; six = 6;})
^
Uncaught SyntaxError: Unexpected token '{'
But none of these errors happen if you put anything (statement or just a semicolon) either before or after the braces.
I am fairly new at JavaScript and Node, so maybe I'm missing something here, but I don't understand how it's okay to use await, and it's okay to run statements in sub-blocks, e.g.
But it apparently is not okay to put await in a sub-block, unless you have a semicolon outside and on the same line. I don't get it. If there is a legit reason for this, the error messages could certainly be more helpful.
The REPL interprets {...} as an object literal. Strictly speaking, it's block syntax but 9 times out of 101 people actually mean to write an object literal, so that's what node interprets it as.
When you prefix it with a semicolon, node knows it must be a block statement because it can't be anything else at that point.
I agree the error message could be better. Pull request welcome.
1 Understatement, it's probably closer to 99 out of a 100.
Strictly speaking, it's block syntax but 9 times out of 10 people actually mean to write an object literal
That would surprise me. I don't see a lot of point in putting in an object literal unless you actually do something with it, like pass it to a function or assign it to a variable. (I guess it is implicitly assigned to _, if people use that feature. I don't.) In fact, running without the REPL, Node preferentially treats curly braces as a block and raises an error if you try to put in just an unused object literal with two or more values:
Also, if you admit that it is block syntax, strictly speaking, but that usually people "actually mean" to write something else, are you saying that the REPL is designed to interpret what you think they meant to say and not what they actually said? Where does that kind of reasoning end? Shouldn't there be a standard to follow?
Note that Firefox console, and possibly other REPLs (didn't test) give the same error, so they also preferentially treat curly braces as blocks. Firefox doesn't choke on {a:1}, but it still doesn't treat it as an object literal. It evaluates to 1. If you want it treated as an object literal, you wrap it in parentheses, i.e. ({a:1}).
But regardless of those things, it is not the case that Node's REPL just always treats {...} as an object literal:
But for some reason it does choke on blocks containing await:
> {const a = 55; await Promise.resolve(a)}
({const a = 55; await Promise.resolve(a)})
^
Uncaught SyntaxError: Unexpected identifier
I don't know the implementation details, but even if it's your goal to have the REPL's behavior not match how things are usually interpreted, and given that these errors are at the level of syntax and not evaluation, couldn't it just see that the input can't be an object literal and try it as a block instead?
It would be nice to be able to just paste portions of a code file into the REPL and not have these puzzling incompatibilities in the way that the main interpreter and the REPL interpret things.
The current behavior was implemented ~12 years ago after extensive feedback from nonplussed users. It's very unlikely to change.
Like I said, pull request welcome to improve the error message. Perhaps it's even possible to improve the scanner to unambiguously detect your await example as a block statement.
Activity
bnoordhuis commentedon Jan 14, 2023
The REPL interprets
{...}as an object literal. Strictly speaking, it's block syntax but 9 times out of 101 people actually mean to write an object literal, so that's what node interprets it as.When you prefix it with a semicolon, node knows it must be a block statement because it can't be anything else at that point.
I agree the error message could be better. Pull request welcome.
1 Understatement, it's probably closer to 99 out of a 100.
mr-bronson commentedon Jan 14, 2023
When it can be, but not always, obviously:
That would surprise me. I don't see a lot of point in putting in an object literal unless you actually do something with it, like pass it to a function or assign it to a variable. (I guess it is implicitly assigned to
_, if people use that feature. I don't.) In fact, running without the REPL, Node preferentially treats curly braces as a block and raises an error if you try to put in just an unused object literal with two or more values:Also, if you admit that it is block syntax, strictly speaking, but that usually people "actually mean" to write something else, are you saying that the REPL is designed to interpret what you think they meant to say and not what they actually said? Where does that kind of reasoning end? Shouldn't there be a standard to follow?
Note that Firefox console, and possibly other REPLs (didn't test) give the same error, so they also preferentially treat curly braces as blocks. Firefox doesn't choke on
{a:1}, but it still doesn't treat it as an object literal. It evaluates to1. If you want it treated as an object literal, you wrap it in parentheses, i.e.({a:1}).But regardless of those things, it is not the case that Node's REPL just always treats
{...}as an object literal:But for some reason it does choke on blocks containing
await:I don't know the implementation details, but even if it's your goal to have the REPL's behavior not match how things are usually interpreted, and given that these errors are at the level of syntax and not evaluation, couldn't it just see that the input can't be an object literal and try it as a block instead?
It would be nice to be able to just paste portions of a code file into the REPL and not have these puzzling incompatibilities in the way that the main interpreter and the REPL interpret things.
bnoordhuis commentedon Jan 18, 2023
The current behavior was implemented ~12 years ago after extensive feedback from nonplussed users. It's very unlikely to change.
Like I said, pull request welcome to improve the error message. Perhaps it's even possible to improve the scanner to unambiguously detect your await example as a block statement.
bnoordhuis commentedon Jan 24, 2023
I'll close this as there's been no follow-up but pull request still welcome.