Skip to content

Instantly share code, notes, and snippets.

@bengl
Last active December 29, 2015 11:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bengl/7662762 to your computer and use it in GitHub Desktop.
Save bengl/7662762 to your computer and use it in GitHub Desktop.
Can't use repl inside domain. Or can I? I'm not sure.

It turns out that the node REPL doesn't seem to behave as expected inside a domain. (I'm using node v0.10.22)

Try running repltest.js, which is narrowed down from a much larger REPL-thing I'm working on. You'll get your REPL, but there is some weirdness. If you give it an empty line (i.e. just press Enter/Return), you'll get a syntax error, captured by the domain and ouput via line 6:

> 
SyntaxError: Unexpected token )
    at REPLServer.self.eval (repl.js:112:21)
    at Interface.<anonymous> (repl.js:239:12)
    at Interface.EventEmitter.emit (events.js:95:17)
    at Interface._onLine (readline.js:202:10)
    at Interface._line (readline.js:531:8)
    at Interface._ttyWrite (readline.js:760:14)
    at ReadStream.onkeypress (readline.js:99:10)
    at ReadStream.EventEmitter.emit (events.js:98:17)
    at emitKey (readline.js:1095:12)
    at ReadStream.onData (readline.js:840:14)

You'll get the exact same error if you try to start writing something incomplete, like the start of a function:

> function hello() {
SyntaxError: Unexpected token )
    at REPLServer.self.eval (repl.js:112:21)
    at Interface.<anonymous> (repl.js:239:12)
    at Interface.EventEmitter.emit (events.js:95:17)
    at Interface._onLine (readline.js:202:10)
    at Interface._line (readline.js:531:8)
    at Interface._ttyWrite (readline.js:760:14)
    at ReadStream.onkeypress (readline.js:99:10)
    at ReadStream.EventEmitter.emit (events.js:98:17)
    at emitKey (readline.js:1095:12)
    at ReadStream.onData (readline.js:840:14)

Looking into this, it looks like the REPL's way of dealing with multi-line things, etc. is to capture SyntaxErrors and toss them in a buffer, so as to execute the chunk as a whole once it's complete, i.e. no longer causing a SyntaxError (See repl.js L274-279). Unfortunately, when you wrap a REPL in a domain, it doesn't call this finish function (See repl.js L117-123).

So the result here is that adding the domain short-circuits some of the code that deals with incomplete input. Hopefully I don't have to re-implement parts of the finish function in my error handler.

Any ideas here? Please tell me if I'm just doing something I shouldn't be doing in the first place. The intention is to not crash when async errors happen in the REPL.

var repl = require('repl');
var d = require('domain').create();
d.on('error', function(err) {
console.error(err.stack || err);
});
d.run(function() {
repl.start('> ');
});
@alexanderscott
Copy link

Appears to be a bug in node pre-v0.11, regarding how REPL evaluates the stdin. Just tested with v0.11.7 and it's fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment