From 9127f34393989718bac537e1a7361a5bdba72c7d Mon Sep 17 00:00:00 2001 From: Bryce Baril Date: Sat, 23 Feb 2013 21:13:20 -0800 Subject: [PATCH] Parser should only catch parser errors and bubble the rest to the caller. Signed-off-by: DTrejo --- lib/parser/javascript.js | 24 ++++++++++++++---------- test.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/lib/parser/javascript.js b/lib/parser/javascript.js index 7bfdb57edf..de8e4602ef 100644 --- a/lib/parser/javascript.js +++ b/lib/parser/javascript.js @@ -24,6 +24,12 @@ util.inherits(ReplyParser, events.EventEmitter); exports.Parser = ReplyParser; +function IncompleteReadBuffer(message) { + this.name = "IncompleteReadBuffer"; + this.message = message; +} +util.inherits(IncompleteReadBuffer, Error); + // Buffer.toString() is quite slow for small strings function small_toString(buf, start, end) { var tmp = "", i; @@ -48,7 +54,7 @@ ReplyParser.prototype._parseResult = function (type) { if (end > this._buffer.length) { this._offset = start; - throw new Error("too far"); + throw new IncompleteReadBuffer("Wait for more data."); } if (this.options.return_buffers) { @@ -70,7 +76,7 @@ ReplyParser.prototype._parseResult = function (type) { if (end > this._buffer.length) { this._offset = start; - throw new Error("too far"); + throw new IncompleteReadBuffer("Wait for more data."); } if (this.options.return_buffers) { @@ -99,7 +105,7 @@ ReplyParser.prototype._parseResult = function (type) { if (end > this._buffer.length) { this._offset = offset; - throw new Error("too far"); + throw new IncompleteReadBuffer("Wait for more data."); } if (this.options.return_buffers) { @@ -129,7 +135,7 @@ ReplyParser.prototype._parseResult = function (type) { ntype = this._buffer[this._offset++]; if (this._offset > this._buffer.length) { - throw new Error("too far"); + throw new IncompleteReadBuffer("Wait for more data."); } res = this._parseResult(ntype); if (res === undefined) { @@ -202,16 +208,14 @@ ReplyParser.prototype.execute = function (buffer) { ret = this._parseResult(type); - if (ret === -1) { - this._offset = offset; - break; - } - this.send_reply(ret); } } catch (err) { // catch the error (not enough data), rewind, and wait // for the next packet to appear + if (! (err instanceof IncompleteReadBuffer)) { + throw err; + } this._offset = offset; break; } @@ -272,7 +276,7 @@ ReplyParser.prototype._packetEndOffset = function () { offset++; if (offset >= this._buffer.length) { - throw new Error("didn't see LF after NL reading multi bulk count (" + offset + " => " + this._buffer.length + ", " + this._offset + ")"); + throw new IncompleteReadBuffer("didn't see LF after NL reading multi bulk count (" + offset + " => " + this._buffer.length + ", " + this._offset + ")"); } } diff --git a/test.js b/test.js index c8a9843654..bb0ca604bf 100644 --- a/test.js +++ b/test.js @@ -291,6 +291,34 @@ tests.MULTI_6 = function () { }); }; +tests.FWD_ERRORS_1 = function () { + var name = "FWD_ERRORS_1"; + + var toThrow = new Error("Forced exception"); + var recordedError = null; + + var originalHandler = client3.listeners("error").pop(); + client3.once("error", function (err) { + recordedError = err; + }); + + client3.on("message", function (channel, data) { + console.log("incoming"); + if (channel == name) { + assert.equal(data, "Some message"); + throw toThrow; + } + }); + client3.subscribe(name); + + client.publish(name, "Some message"); + setTimeout(function () { + client3.listeners("error").push(originalHandler); + assert.equal(recordedError, toThrow, "Should have caught our forced exception"); + next(name); + }, 150); +}; + tests.EVAL_1 = function () { var name = "EVAL_1";