Skip to content

Commit b9f6453

Browse files
committed
repl: better handling of recoverable errors
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.
1 parent 16facd7 commit b9f6453

File tree

2 files changed

+75
-10
lines changed

2 files changed

+75
-10
lines changed

lib/repl.js

+6-5
Original file line numberDiff line numberDiff line change
@@ -1454,14 +1454,15 @@ function isRecoverableError(e, code) {
14541454
if (e && e.name === 'SyntaxError') {
14551455
var message = e.message;
14561456
if (message === 'Unterminated template literal' ||
1457-
message === 'Missing } in template expression') {
1457+
message === 'Unexpected end of input') {
14581458
return true;
14591459
}
14601460

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

14661467
if (message === 'Invalid or unexpected token')
14671468
return isCodeRecoverable(code);

test/parallel/test-repl.js

+69-5
Original file line numberDiff line numberDiff line change
@@ -163,13 +163,23 @@ const errorTests = [
163163
send: '.break',
164164
expect: ''
165165
},
166-
// Template expressions can cross lines
166+
// Template expressions
167167
{
168168
send: '`io.js ${"1.0"',
169+
expect: [
170+
kSource,
171+
kArrow,
172+
'',
173+
/^SyntaxError: /,
174+
''
175+
]
176+
},
177+
{
178+
send: '`io.js ${',
169179
expect: '... '
170180
},
171181
{
172-
send: '+ ".2"}`',
182+
send: '"1.0" + ".2"}`',
173183
expect: '\'io.js 1.0.2\''
174184
},
175185
// Dot prefix in multiline commands aren't treated as commands
@@ -644,14 +654,68 @@ const errorTests = [
644654
},
645655
// Do not parse `...[]` as a REPL keyword
646656
{
647-
send: '...[]\n',
648-
expect: '... ... '
657+
send: '...[]',
658+
expect: [
659+
kSource,
660+
kArrow,
661+
'',
662+
/^SyntaxError: /,
663+
''
664+
]
649665
},
650666
// bring back the repl to prompt
651667
{
652668
send: '.break',
653669
expect: ''
654-
}
670+
},
671+
{
672+
send: 'console.log("Missing comma in arg list" process.version)',
673+
expect: [
674+
kSource,
675+
kArrow,
676+
'',
677+
/^SyntaxError: /,
678+
''
679+
]
680+
},
681+
{
682+
send: 'x = {\nfield\n{',
683+
expect: [
684+
'... ... {',
685+
kArrow,
686+
'',
687+
/^SyntaxError: /,
688+
''
689+
]
690+
},
691+
{
692+
send: '(2 + 3))',
693+
expect: [
694+
kSource,
695+
kArrow,
696+
'',
697+
/^SyntaxError: /,
698+
''
699+
]
700+
},
701+
{
702+
send: 'if (typeof process === "object"); {',
703+
expect: '... '
704+
},
705+
{
706+
send: 'console.log("process is defined");',
707+
expect: '... '
708+
},
709+
{
710+
send: '} else {',
711+
expect: [
712+
kSource,
713+
kArrow,
714+
'',
715+
/^SyntaxError: /,
716+
''
717+
]
718+
},
655719
];
656720

657721
const tcpTests = [

0 commit comments

Comments
 (0)