pengz
pengz

Reputation: 2471

NodeJS Redis (ioredis) hgetall throwing undefined error

I am building a NodeJS app that connects to a Redis cluster using the ioredis module.

Overview of the issue:

I created a controller to create and manage the connection:

const redis = require('ioredis');
const consoleLogger = require('../logger/logger.js').console;

const redisCtrl = {};

redisCtrl.defaultPrefix = 'lookup:';

// Local variable to store the full time connection to Redis for lookups
let _redisClient;

// Redis connection config
redisCtrl.redisConnect = {
  port: process.env.REDIS_PORT || 6379,
  host: process.env.REDIS_HOST,
  password: process.env.REDIS_PASSWORD
};

// Redis config
redisCtrl.redisConfig = {
  dnsLookup: (address, callback) => callback(null, address),
  redisOptions: {
    tls: process.env.REDIS_SSL === 'false' ? false : true,
    password: process.env.REDIS_PASSWORD,
    maxRetriesPerRequest: 1
  }
};

// Retrieve the redis connection
redisCtrl.redisClient = async () => {
  if (!_redisClient) {
    _redisClient = await redisCtrl.getNewConnect();
  }
  return _redisClient;
}

redisCtrl.getNewConnect = async () => {
  let makeConnection;

  if (process.env.REDIS_CLUSTER === 'true') {
    makeConnection = new redis.Cluster([redisCtrl.redisConnect], redisCtrl.redisConfig);
  } else {
    makeConnection = new redis(redisCtrl.redisConnect);
  }

  makeConnection.on("connect", function (err) {
    if (!err) {
      consoleLogger.info("REDIS connected");
    } else {
      consoleLogger.info("REDIS connection error");
      consoleLogger.error(JSON.stringify(err));
    }
  });

  makeConnection.on("error", function (error) {
    consoleLogger.info("REDIS error");
    consoleLogger.error(JSON.stringify(error));
    throw new Error(error);
  });

  return makeConnection;
}

redisCtrl.closeInstance = (cb) => {
  if (_redisClient) {
    _redisClient.quit(cb);
  }
}

module.exports = redisCtrl;

This works to establish the connection.

However, when attempting to get a result, an empty error is thrown from the hgetall method.

/**
 * Lookup asset by assetId in Redis cache
 * Return asset data object
 * @param {str} assetId
 */
assetsCtrl.lookupByAssetId = async (assetId) => {
  // Prepend default cache prefix to lookup value
  const lookupKey = `${redisPrefix || `lookup:`}${assetId}`;
  let cachedAsset;
  try {
    cachedAsset = await assetsCtrl.redisClient.hgetall(lookupKey);
  } catch (e) {
    consoleLogger.error(`Lookup by assetId failed. Lookup key: ${lookupKey}`);
    consoleLogger.error(e);
    throw new Error(e);
  }
  return cachedAsset;
}

The error is thrown but the error is undefined. The "catch" block of the redisClient.hgetall(lookupKey) line is getting called but the error is not defined.

error: Lookup by assetId failed. Lookup key: lookup:test123456789
**error: undefined {"command":{"name":"hget","args":["lookup:test123456789"]}}**

Questions: How can I troubleshoot this issue? How can I see the details of the error that is being thrown?

Upvotes: 0

Views: 1685

Answers (1)

Suyash Gaur
Suyash Gaur

Reputation: 2881

As stated in the comments above,
the hgetall() is not working because the datatype corresponding to the lookup value was not hash.

Changing it to get() has fixed the issue.

Upvotes: 1

Related Questions