Skip to content

Commit

Permalink
repl: better handling of recoverable errors
Browse files Browse the repository at this point in the history
Below syntax errors are handled without force .break/clear
  - Unexpected Token (prefix errors)
  - missing ) after argument list

In the multiline expression, recoverable errors are truly
recoverable, otherwise syntax error will be thrown.

PR-URL: nodejs#18915
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Shingo Inoue <leko.noor@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
  • Loading branch information
princejwesley authored and jasnell committed Aug 17, 2018
1 parent ac6f9d5 commit 8c206d7
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 10 deletions.
11 changes: 6 additions & 5 deletions lib/repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -1337,14 +1337,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 @@ -165,13 +165,23 @@ const errorTests = [
send: '.break',
expect: ''
},
// Template expressions can cross lines
// Template expressions
{
send: '`io.js ${"1.0"',
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 @@ -636,14 +646,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

0 comments on commit 8c206d7

Please sign in to comment.