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: diff --git a/index.js b/index.js index 3455fb8bdc..b45902a931 100644 --- a/index.js +++ b/index.js @@ -1014,7 +1014,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) { @@ -1040,7 +1040,7 @@ Multi.prototype.exec = function (callback) { if (typeof cur[cur.length - 1] === "function") { cur[cur.length - 1](err); } else { - throw new Error(err); + errors.push(new Error(err)); } self.queue.splice(index, 1); } @@ -1051,7 +1051,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 f5fcffb24f..07c6b42a42 100644 --- a/test.js +++ b/test.js @@ -320,6 +320,19 @@ tests.MULTI_7 = function () { next(name); }; + +tests.MULTI_EXCEPTION_1 = function() { + var name = "MULTI_EXCEPTION_1"; + + client.multi().set("foo").exec(function (err, reply) { + 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); + }); +}; + tests.FWD_ERRORS_1 = function () { var name = "FWD_ERRORS_1"; @@ -615,7 +628,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);