From c7633bf738ec6565f59076066bc73df3bcb5df4a Mon Sep 17 00:00:00 2001 From: Thanasis Polychronakis Date: Thu, 18 Apr 2013 21:48:35 +0300 Subject: [PATCH 1/4] fix unescaped exception in Multi.exec --- index.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 6bc76d54a1..fcca3feba1 100644 --- a/index.js +++ b/index.js @@ -713,7 +713,7 @@ RedisClient.prototype.send_command = function (command, args, callback) { return callback(err); } } - + buffer_args = false; for (i = 0, il = args.length, arg; i < il; i += 1) { if (Buffer.isBuffer(args[i])) { @@ -1037,7 +1037,12 @@ Multi.prototype.exec = function (callback) { if (typeof cur[cur.length - 1] === "function") { cur[cur.length - 1](err); } else { - throw new Error(err); + if (callback) { + callback(new Error(err)); + return; + } else { + throw new Error(err); + } } self.queue.splice(index, 1); } From ed57dcd9d5c594b8efc74bb20453dcbc7cdddb4d Mon Sep 17 00:00:00 2001 From: Thanasis Polychronakis Date: Thu, 18 Apr 2013 22:25:58 +0300 Subject: [PATCH 2/4] handling of errors on multi, now returns 'err' array type --- index.js | 12 ++++-------- test.js | 11 ++++++++++- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/index.js b/index.js index fcca3feba1..5f46888110 100644 --- a/index.js +++ b/index.js @@ -1011,7 +1011,7 @@ Multi.prototype.HMSET = Multi.prototype.hmset; Multi.prototype.exec = function (callback) { var self = this; - + var errors = []; // drain queue, callback will catch "QUEUED" or error // TODO - get rid of all of these anonymous functions which are elegant but slow this.queue.forEach(function (args, index) { @@ -1037,12 +1037,7 @@ Multi.prototype.exec = function (callback) { if (typeof cur[cur.length - 1] === "function") { cur[cur.length - 1](err); } else { - if (callback) { - callback(new Error(err)); - return; - } else { - throw new Error(err); - } + errors.push(new Error(err)); } self.queue.splice(index, 1); } @@ -1053,7 +1048,8 @@ Multi.prototype.exec = function (callback) { return this._client.send_command("EXEC", [], function (err, replies) { if (err) { if (callback) { - callback(new Error(err)); + errors.push(new Error(err)); + callback(errors); return; } else { throw new Error(err); diff --git a/test.js b/test.js index 1d8d6343af..07ddcf97cb 100644 --- a/test.js +++ b/test.js @@ -320,6 +320,15 @@ tests.MULTI_7 = function () { next(name); }; + +tests.MULTI_EXCEPTION_1 = function() { + client.multi().set("foo").exec(function (err, reply) { + /* ... */ + console.log('CB:', arguments); + }); + // [Error: Error: ERR wrong number of arguments for 'set' command] +}; + tests.FWD_ERRORS_1 = function () { var name = "FWD_ERRORS_1"; @@ -615,7 +624,7 @@ tests.detect_buffers = function () { assert.strictEqual("", reply[0].inspect(), name); assert.strictEqual("", reply[1].inspect(), name); }); - + // array of strings with undefined values (repro #344) detect_client.hmget("hash key 2", "key 3", "key 4", function(err, reply) { assert.strictEqual(null, err, name); From a86720097e42e3dc4208d1ee6e6f769a4a58a872 Mon Sep 17 00:00:00 2001 From: Thanasis Polychronakis Date: Fri, 19 Apr 2013 15:40:53 +0300 Subject: [PATCH 3/4] added test for MULTI exception --- test.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/test.js b/test.js index 07ddcf97cb..832de4062b 100644 --- a/test.js +++ b/test.js @@ -322,11 +322,15 @@ tests.MULTI_7 = function () { tests.MULTI_EXCEPTION_1 = function() { + var name = "MULTI_EXCEPTION_1"; + client.multi().set("foo").exec(function (err, reply) { - /* ... */ - console.log('CB:', arguments); + assert(Array.isArray(err), "err should be an array"); + assert.equal(2, err.length, "err should have 2 items"); + assert(err[0].message.match(/ERR/), "First error message should contain ERR"); + assert(err[1].message.match(/EXECABORT/), "First error message should contain EXECABORT"); + next(name); }); - // [Error: Error: ERR wrong number of arguments for 'set' command] }; tests.FWD_ERRORS_1 = function () { From 802539b07e44e577a488601df2eb8d7c6200f35a Mon Sep 17 00:00:00 2001 From: Thanasis Polychronakis Date: Fri, 19 Apr 2013 15:49:32 +0300 Subject: [PATCH 4/4] update docs for MULTI exception --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index b8237f0043..545ffe9911 100644 --- a/README.md +++ b/README.md @@ -411,10 +411,17 @@ Redis. The interface in `node_redis` is to return an individual `Multi` object }); ``` +### Multi.exec( callback ) + `client.multi()` is a constructor that returns a `Multi` object. `Multi` objects share all of the same command methods as `client` objects do. Commands are queued up inside the `Multi` object until `Multi.exec()` is invoked. +The `callback` of `.exec()` will get invoked with two arguments: + +* `err` **type:** `null | Array` err is either null or an array of Error Objects corresponding the the sequence the commands where chained. The last item of the array will always be an `EXECABORT` type of error originating from the `.exec()` itself. +* `results` **type:** `null | Array` results is an array of responses corresponding the the sequence the commands where chained. + You can either chain together `MULTI` commands as in the above example, or you can queue individual commands while still sending regular client command as in this example: