From c60a3b65fec2b3614741ecae54de8f0c1e42a711 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Sun, 20 Sep 2015 18:56:21 +0200 Subject: [PATCH] Rename .command_used to .command and add the used command to more errors --- index.js | 47 +++++++++++++++++++++--------------- test/auth.spec.js | 8 +++--- test/commands/multi.spec.js | 4 ++- test/commands/select.spec.js | 2 +- test/node_redis.spec.js | 8 +++--- 5 files changed, 40 insertions(+), 29 deletions(-) diff --git a/index.js b/index.js index c4ffba1923..98685f41a3 100644 --- a/index.js +++ b/index.js @@ -503,8 +503,11 @@ RedisClient.prototype.connection_gone = function (why) { var err_code = /^([A-Z]+)\s+(.+)$/; RedisClient.prototype.return_error = function (err) { var command_obj = this.command_queue.shift(), queue_len = this.command_queue.length; + // send_command might have been used wrong => catch those cases too if (command_obj.command && command_obj.command.toUpperCase) { - err.command_used = command_obj.command.toUpperCase(); + err.command = command_obj.command.toUpperCase(); + } else { + err.command = command_obj.command; } var match = err.message.match(err_code); @@ -652,7 +655,9 @@ RedisClient.prototype.return_reply = function (reply) { }); this.emit("monitor", timestamp, args); } else { - this.emit("error", new Error("node_redis command queue state error. If you can reproduce this, please report it.")); + var err = new Error("node_redis command queue state error. If you can reproduce this, please report it."); + err.command = command_obj.command.toUpperCase(); + this.emit("error", err); } }; @@ -706,7 +711,7 @@ RedisClient.prototype.send_command = function (command, args, callback) { if (args[args.length - 1] === undefined || args[args.length - 1] === null) { command = command.toUpperCase(); err = new Error('send_command: ' + command + ' value must not be undefined or null'); - err.command_used = command; + err.command = command; if (callback) { return callback && callback(err); } @@ -733,7 +738,7 @@ RedisClient.prototype.send_command = function (command, args, callback) { } else { err = new Error(command + ' can\'t be processed. The connection has already been closed.'); } - err.command_used = command; + err.command = command; if (callback) { callback(err); } else { @@ -754,7 +759,9 @@ RedisClient.prototype.send_command = function (command, args, callback) { } else if (command === "quit") { this.closing = true; } else if (this.pub_sub_mode === true) { - this.emit("error", new Error("Connection in subscriber mode, only subscriber commands may be used")); + err = new Error("Connection in subscriber mode, only subscriber commands may be used"); + err.command = command.toUpperCase(); + this.emit("error", err); return; } this.command_queue.push(command_obj); @@ -935,7 +942,7 @@ RedisClient.prototype.select = RedisClient.prototype.SELECT = function (db, call RedisClient.prototype.auth = RedisClient.prototype.AUTH = function (pass, callback) { if (typeof pass !== 'string') { var err = new Error('The password has to be of type "string"'); - err.command_used = 'AUTH'; + err.command = 'AUTH'; if (callback) { callback(err); } else { @@ -1056,7 +1063,7 @@ Multi.prototype.exec = Multi.prototype.EXEC = function (callback) { }; Multi.prototype.execute_callback = function (err, replies) { - var i, reply, args; + var i, args; if (err) { if (err.code !== 'CONNECTION_BROKEN') { @@ -1072,32 +1079,32 @@ Multi.prototype.execute_callback = function (err, replies) { } if (replies) { - for (i = 1; i < this.queue.length; i += 1) { - reply = replies[i - 1]; - args = this.queue[i]; + for (i = 0; i < this.queue.length - 1; i += 1) { + args = this.queue[i + 1]; // If we asked for strings, even in detect_buffers mode, then return strings: - if (reply instanceof Error) { - var match = reply.message.match(err_code); + if (replies[i] instanceof Error) { + var match = replies[i].message.match(err_code); // LUA script could return user errors that don't behave like all other errors! if (match) { - reply.code = match[1]; + replies[i].code = match[1]; } - } else if (reply) { - if (this._client.options.detect_buffers && this.wants_buffers[i] === false) { - replies[i - 1] = reply = reply_to_strings(reply); + replies[i].command = args[0].toUpperCase(); + } else if (replies[i]) { + if (this._client.options.detect_buffers && this.wants_buffers[i + 1] === false) { + replies[i] = reply_to_strings(replies[i]); } if (args[0] === "hgetall") { // TODO - confusing and error-prone that hgetall is special cased in two places - replies[i - 1] = reply = reply_to_object(reply); + replies[i] = reply_to_object(replies[i]); } } if (typeof args[args.length - 1] === "function") { - if (reply instanceof Error) { - args[args.length - 1](reply); + if (replies[i] instanceof Error) { + args[args.length - 1](replies[i]); } else { - args[args.length - 1](null, reply); + args[args.length - 1](null, replies[i]); } } } diff --git a/test/auth.spec.js b/test/auth.spec.js index f127005926..15ec18fe22 100644 --- a/test/auth.spec.js +++ b/test/auth.spec.js @@ -41,7 +41,7 @@ describe("client authentication", function () { client = redis.createClient.apply(redis.createClient, args); client.once('error', function (err) { - assert.strictEqual(err.command_used, 'AUTH'); + assert.strictEqual(err.command, 'AUTH'); assert.ok(/ERR invalid password/.test(err.message)); return done(); }); @@ -55,7 +55,7 @@ describe("client authentication", function () { client = redis.createClient.apply(redis.createClient, args); client.auth('', function (err, res) { - assert.strictEqual(err.command_used, 'AUTH'); + assert.strictEqual(err.command, 'AUTH'); assert.ok(/ERR invalid password/.test(err.message)); done(); }); @@ -130,7 +130,7 @@ describe("client authentication", function () { client = redis.createClient.apply(redis.createClient, args); client.auth(undefined, function(err, res) { assert.strictEqual(err.message, 'The password has to be of type "string"'); - assert.strictEqual(err.command_used, 'AUTH'); + assert.strictEqual(err.command, 'AUTH'); assert.strictEqual(res, undefined); done(); }); @@ -142,7 +142,7 @@ describe("client authentication", function () { client = redis.createClient.apply(redis.createClient, args); client.on('error', function (err) { assert.strictEqual(err.message, 'The password has to be of type "string"'); - assert.strictEqual(err.command_used, 'AUTH'); + assert.strictEqual(err.command, 'AUTH'); done(); }); client.auth(234567); diff --git a/test/commands/multi.spec.js b/test/commands/multi.spec.js index 840eb9687c..af73235891 100644 --- a/test/commands/multi.spec.js +++ b/test/commands/multi.spec.js @@ -253,7 +253,7 @@ describe("The 'multi' method", function () { assert.equal(reply, undefined, "The reply should have been discarded"); assert(err.message.match(/^EXECABORT/), "Error message should begin with EXECABORT"); assert.equal(err.errors.length, 2, "err.errors should have 2 items"); - assert.strictEqual(err.errors[0].command_used, 'SET'); + assert.strictEqual(err.errors[0].command, 'SET'); assert.strictEqual(err.errors[0].code, 'ERR'); assert.strictEqual(err.errors[0].position, 1); assert(/^ERR/.test(err.errors[0].message), "Actuall error message should begin with ERR"); @@ -265,7 +265,9 @@ describe("The 'multi' method", function () { client.multi().config("bar").debug("foo").eval("return {err='this is an error'}", 0).exec(function (err, reply) { assert.strictEqual(reply.length, 3); assert.equal(reply[0].code, 'ERR'); + assert.equal(reply[0].command, 'CONFIG'); assert.equal(reply[2].code, undefined); + assert.equal(reply[2].command, 'EVAL'); assert(/^this is an error/.test(reply[2].message)); assert(/^ERR/.test(reply[0].message), "Error message should begin with ERR"); assert(/^ERR/.test(reply[1].message), "Error message should begin with ERR"); diff --git a/test/commands/select.spec.js b/test/commands/select.spec.js index c02b4de543..832d5ffac1 100644 --- a/test/commands/select.spec.js +++ b/test/commands/select.spec.js @@ -94,7 +94,7 @@ describe("The 'select' method", function () { assert.strictEqual(client.selected_db, null, "default db should be null"); client.on('error', function (err) { - assert.strictEqual(err.command_used, 'SELECT'); + assert.strictEqual(err.command, 'SELECT'); assert.equal(err.message, 'ERR invalid DB index'); done(); }); diff --git a/test/node_redis.spec.js b/test/node_redis.spec.js index 3a90a94419..2178cf16a1 100644 --- a/test/node_redis.spec.js +++ b/test/node_redis.spec.js @@ -156,7 +156,9 @@ describe("The node_redis client", function () { process.once('uncaughtException', function (err) { process.on('uncaughtException', mochaListener); - assert(/ERR Protocol error/.test(err)); + assert(/ERR Protocol error/.test(err.message)); + assert.equal(err.command, true); + assert.equal(err.code, 'ERR'); done(); }); @@ -195,7 +197,7 @@ describe("The node_redis client", function () { setTimeout(function() { client.get("foo", function(err, res) { assert.strictEqual(err.message, 'GET can\'t be processed. The connection has already been closed.'); - assert.strictEqual(err.command_used, 'GET'); + assert.strictEqual(err.command, 'GET'); assert.strictEqual(client.offline_queue.length, 0); done(); }); @@ -209,7 +211,7 @@ describe("The node_redis client", function () { client.quit(); client.on('error', function(err) { assert.strictEqual(err.message, 'SET can\'t be processed. The connection has already been closed.'); - assert.strictEqual(err.command_used, 'SET'); + assert.strictEqual(err.command, 'SET'); assert.strictEqual(client.offline_queue.length, 0); done(); });