-
Notifications
You must be signed in to change notification settings - Fork 29.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
repl: do not swallow errors in nested REPLs
For tab completion, a REPLServer instance will sometimes create another REPLServer instance. If a callback is sent to the `.complete()` function and that callback throws an error, it will be swallowed by the nested REPLs domain. Re-throw the error so that processes don't silently exit without any indication of an error (including a status code). Fixes: #21586 PR-URL: #23004 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
- Loading branch information
Showing
4 changed files
with
73 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Tab completion sometimes uses a separate REPL instance under the hood. | ||
// That REPL instance has its own domain. Make sure domain errors trickle back | ||
// up to the main REPL. | ||
// | ||
// Ref: https://github.com/nodejs/node/issues/21586 | ||
|
||
'use strict'; | ||
|
||
const { Stream } = require('stream'); | ||
const { inherits } = require('util'); | ||
function noop() {} | ||
|
||
// A stream to push an array into a REPL | ||
function ArrayStream() { | ||
this.run = function(data) { | ||
data.forEach((line) => { | ||
this.emit('data', `${line}\n`); | ||
}); | ||
}; | ||
} | ||
|
||
inherits(ArrayStream, Stream); | ||
ArrayStream.prototype.readable = true; | ||
ArrayStream.prototype.writable = true; | ||
ArrayStream.prototype.pause = noop; | ||
ArrayStream.prototype.resume = noop; | ||
ArrayStream.prototype.write = noop; | ||
|
||
const repl = require('repl'); | ||
|
||
const putIn = new ArrayStream(); | ||
const testMe = repl.start('', putIn); | ||
|
||
// Some errors are passed to the domain, but do not callback | ||
testMe._domain.on('error', function(err) { | ||
throw err; | ||
}); | ||
|
||
// Nesting of structures causes REPL to use a nested REPL for completion. | ||
putIn.run([ | ||
'var top = function() {', | ||
'r = function test (', | ||
' one, two) {', | ||
'var inner = {', | ||
' one:1', | ||
'};' | ||
]); | ||
|
||
// In Node.js 10.11.0, this next line will terminate the repl silently... | ||
testMe.complete('inner.o', () => { throw new Error('fhqwhgads'); }); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// Tab completion sometimes uses a separate REPL instance under the hood. | ||
// That REPL instance has its own domain. Make sure domain errors trickle back | ||
// up to the main REPL. | ||
// | ||
// Ref: https://github.com/nodejs/node/issues/21586 | ||
|
||
'use strict'; | ||
|
||
require('../common'); | ||
const fixtures = require('../common/fixtures'); | ||
|
||
const assert = require('assert'); | ||
const { spawnSync } = require('child_process'); | ||
|
||
const testFile = fixtures.path('repl-tab-completion-nested-repls.js'); | ||
const result = spawnSync(process.execPath, [testFile]); | ||
|
||
// The spawned process will fail. In Node.js 10.11.0, it will fail silently. The | ||
// test here is to make sure that the error information bubbles up to the | ||
// calling process. | ||
assert.ok(result.status, 'testFile swallowed its error'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters