readline: fix freeze if keypress
event throws
`emitKeys` is a generator which emits `keypress` events in an infinite loop. But if `keypress` event handler throws, the error stops the loop, leaving generator in a broken state. So this patch restarts the generator when an error occures. PR-URL: https://github.com/nodejs/io.js/pull/2107 Reviewed-By: Christopher Monsanto <chris@monsan.to> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
This commit is contained in:
parent
cf14a2427c
commit
bd01603201
@ -910,7 +910,15 @@ function emitKeypressEvents(stream) {
|
|||||||
var r = stream[KEYPRESS_DECODER].write(b);
|
var r = stream[KEYPRESS_DECODER].write(b);
|
||||||
if (r) {
|
if (r) {
|
||||||
for (var i = 0; i < r.length; i++) {
|
for (var i = 0; i < r.length; i++) {
|
||||||
stream[ESCAPE_DECODER].next(r[i]);
|
try {
|
||||||
|
stream[ESCAPE_DECODER].next(r[i]);
|
||||||
|
} catch (err) {
|
||||||
|
// if the generator throws (it could happen in the `keypress`
|
||||||
|
// event), we need to restart it.
|
||||||
|
stream[ESCAPE_DECODER] = emitKeys(stream);
|
||||||
|
stream[ESCAPE_DECODER].next();
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -192,6 +192,24 @@ function isWarned(emitter) {
|
|||||||
assert.equal(callCount, 1);
|
assert.equal(callCount, 1);
|
||||||
rli.close();
|
rli.close();
|
||||||
|
|
||||||
|
// Regression test for repl freeze, #1968:
|
||||||
|
// check that nothing fails if 'keypress' event throws.
|
||||||
|
fi = new FakeInput();
|
||||||
|
rli = new readline.Interface({ input: fi, output: fi, terminal: true });
|
||||||
|
var keys = [];
|
||||||
|
fi.on('keypress', function(key) {
|
||||||
|
keys.push(key);
|
||||||
|
if (key === 'X') {
|
||||||
|
throw new Error('bad thing happened');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
fi.emit('data', 'fooX');
|
||||||
|
} catch(e) { }
|
||||||
|
fi.emit('data', 'bar');
|
||||||
|
assert.equal(keys.join(''), 'fooXbar');
|
||||||
|
rli.close();
|
||||||
|
|
||||||
// calling readline without `new`
|
// calling readline without `new`
|
||||||
fi = new FakeInput();
|
fi = new FakeInput();
|
||||||
rli = readline.Interface({ input: fi, output: fi, terminal: terminal });
|
rli = readline.Interface({ input: fi, output: fi, terminal: terminal });
|
||||||
|
Loading…
x
Reference in New Issue
Block a user