shau
shau

Reputation: 153

Error using Redis Multi with nodejs

I am using Redis and consulting it from nodejs, using the module Redis.

When i exec a client.multi() and the redis server is down the callback doesn't send the error and the nodejs app terminates. This is the error

    /Users/a/db/node_modules/redis/index.js:151
                    throw callback_err;
                          ^
TypeError: Cannot read property 'length' of undefined
    at Command.callback (/Users/a/db/node_modules/redis/index.js:1098:35)
    at RedisClient.flush_and_error (/Users/a/db/node_modules/redis/index.js:148:29)
    at RedisClient.on_error (/Users/a/db/node_modules/redis/index.js:184:10)
    at Socket.<anonymous> (/Users/a/db/node_modules/redis/index.js:95:14)
    at Socket.EventEmitter.emit (events.js:95:17)
    at net.js:441:14
    at process._tickCallback (node.js:415:13)

this is my code: Constructor class

var redis = require('redis');
var client;
function Redis(){
    client = redis.createClient();
    client.on("error", function (err) {
        console.log("Error " + err);
    });
}

Redis.prototype.multi =  function(commands,callback){
    var err = null;
    client.multi(commands).exec(function (error, res) {
        if(error){
            process.nextTick(function(){
                callback(error,null)
            })
        }else{
            process.nextTick(function(){
                callback(null,res)
            })
        }
    });
}

Upvotes: 0

Views: 4821

Answers (2)

matan yemini
matan yemini

Reputation: 161

I think that people are still reaching here... (not sure if this answers this specific question directly, but I assume people reaching here since the multi.exec() returns true / the event loop is not waiting for it's response.

After the fixes that went in (in node-redis), it is possible to wrap the result of exec with Promise, and then you will be sure that the result will include the replies from the multi.

So, you can add some redis commands to the multi:

await multi.exists(key);
await multi.sadd(key2,member);

And then in the result do something like:

    return new Promise((resolve, reject) => {
        multi.exec((err, replies) => {
            if (err) {
                reject(err);
            }
            return resolve(replies);
        });
    });

Otherwise, if you will just do: const reply = await multi.exec(); it will just return you true, and not the replies

** Important to mention - this refers to 'async-redis' and 'node-redis'

Upvotes: 0

Paul Banks
Paul Banks

Reputation: 21

FYI, I ran across this in an old lib that depended on old version of node_redis.

This issue was a bug and was fixed in v0.9.1 - November 23, 2013: https://github.com/mranney/node_redis/pull/457

Upvotes: 1

Related Questions