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

repl: better handling of recoverable errors #18915

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions lib/repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -1454,14 +1454,15 @@ function isRecoverableError(e, code) {
if (e && e.name === 'SyntaxError') {
var message = e.message;
if (message === 'Unterminated template literal' ||
message === 'Missing } in template expression') {
message === 'Unexpected end of input') {
return true;
}

if (message.startsWith('Unexpected end of input') ||
message.startsWith('missing ) after argument list') ||
message.startsWith('Unexpected token'))
return true;
if (message === 'missing ) after argument list') {
const frames = e.stack.split(/\r?\n/);
const pos = frames.findIndex((f) => f.match(/^\s*\^+$/));
return pos > 0 && frames[pos - 1].length === frames[pos].length;
}

if (message === 'Invalid or unexpected token')
return isCodeRecoverable(code);
Expand Down
74 changes: 69 additions & 5 deletions test/parallel/test-repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,23 @@ const errorTests = [
send: '.break',
expect: ''
},
// Template expressions can cross lines
// Template expressions
{
send: '`io.js ${"1.0"',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess recovering from e.g.

'`abc ${ test'

is not possible anymore?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, only some forms are not possible. For instance, below one is possible.

`abc ${
   test}`

Its mostly consistent with chrome console behaviour except for couple of cases.

  1. we handle 'missing ) after argument list' error better than chrome console.
  2. we allow repl commands in multiline mode which should otherwise be treated as properties/functions.
    princejwesley@c1796b8 (wip)
> (function() {
... x = { help: () => 'help received' };
... return x
...         .help ();    <-- no repl command parsing in multiline mode
.break    Sometimes you get stuck, this gets you out
.clear    Alias for .break
.editor   Enter editor mode
.exit     Exit the repl
.help     Print this help message
.load     Load JS from a file into the REPL session
.save     Save all evaluated commands in this REPL session to a file
...

(I'll give PR over the weekend)

expect: [
kSource,
kArrow,
'',
/^SyntaxError: /,
''
]
},
{
send: '`io.js ${',
expect: '... '
},
{
send: '+ ".2"}`',
send: '"1.0" + ".2"}`',
expect: '\'io.js 1.0.2\''
},
// Dot prefix in multiline commands aren't treated as commands
Expand Down Expand Up @@ -644,14 +654,68 @@ const errorTests = [
},
// Do not parse `...[]` as a REPL keyword
{
send: '...[]\n',
expect: '... ... '
send: '...[]',
expect: [
kSource,
kArrow,
'',
/^SyntaxError: /,
''
]
},
// bring back the repl to prompt
{
send: '.break',
expect: ''
}
},
{
send: 'console.log("Missing comma in arg list" process.version)',
expect: [
kSource,
kArrow,
'',
/^SyntaxError: /,
''
]
},
{
send: 'x = {\nfield\n{',
expect: [
'... ... {',
kArrow,
'',
/^SyntaxError: /,
''
]
},
{
send: '(2 + 3))',
expect: [
kSource,
kArrow,
'',
/^SyntaxError: /,
''
]
},
{
send: 'if (typeof process === "object"); {',
expect: '... '
},
{
send: 'console.log("process is defined");',
expect: '... '
},
{
send: '} else {',
expect: [
kSource,
kArrow,
'',
/^SyntaxError: /,
''
]
},
];

const tcpTests = [
Expand Down