diff --git a/index.js b/index.js index 2f840ecfed..94d213e92f 100644 --- a/index.js +++ b/index.js @@ -530,6 +530,8 @@ RedisClient.prototype.connection_gone = function (why) { // error.message = 'Command aborted in uncertain state and queued for next connection.'; // } this.flush_and_error(error, ['command_queue']); + error.message = 'Redis connection lost and commands aborted in uncertain state. They might have been processed.'; + this.emit('error', error); } if (this.retry_max_delay !== null && this.retry_delay > this.retry_max_delay) { @@ -1109,11 +1111,12 @@ Multi.prototype.execute_callback = function (err, replies) { if (err) { // The errors would be circular - err.errors = err.code !== 'CONNECTION_BROKEN' ? this.errors : []; + var connection_error = ['CONNECTION_BROKEN', 'UNCERTAIN_STATE'].indexOf(err.code) !== -1; + err.errors = connection_error ? [] : this.errors; if (this.callback) { this.callback(err); - } else if (err.code !== 'CONNECTION_BROKEN') { - // Exclude CONNECTION_BROKEN so that error won't be emitted twice + // Exclude connection errors so that those errors won't be emitted twice + } else if (!connection_error) { this._client.emit('error', err); } return; diff --git a/test/commands/multi.spec.js b/test/commands/multi.spec.js index 062d14c32c..ea26fdfb50 100644 --- a/test/commands/multi.spec.js +++ b/test/commands/multi.spec.js @@ -553,6 +553,19 @@ describe("The 'multi' method", function () { }); }); + it("emits error once if reconnecting after multi has been executed but not yet returned without callback", function (done) { + helper.serverVersionAtLeast.call(this, client, [2, 6, 5]); + + client.on('error', function(err) { + assert.strictEqual(err.code, 'UNCERTAIN_STATE'); + done(); + }); + + client.multi().set("foo", 'bar').get('foo').exec(); + // Abort connection before the value returned + client.stream.destroy(); + }); + }); }); }); diff --git a/test/connection.spec.js b/test/connection.spec.js index 1fda737951..62251fdef4 100644 --- a/test/connection.spec.js +++ b/test/connection.spec.js @@ -107,6 +107,20 @@ describe("connection tests", function () { }); }); + + it("emits error once if reconnecting after command has been executed but not yet returned without callback", function (done) { + client = redis.createClient.apply(redis.createClient, args); + client.on('error', function(err) { + assert.strictEqual(err.code, 'UNCERTAIN_STATE'); + done(); + }); + + client.on('ready', function() { + client.set("foo", 'bar'); + // Abort connection before the value returned + client.stream.destroy(); + }); + }); }); describe("when not connected", function () {