NodeJS Redis (ioredis) hgetall выдает неопределенную ошибку

#node.js #redis #ioredis

Вопрос:

Я создаю приложение NodeJS, которое подключается к кластеру Redis с помощью модуля ioredis.

Обзор проблемы:

  • Запрос на поиск ключа, которого нет в кэше, возвращает пустой объект, как и ожидалось
  • Запрос поиска ключа, который существует в кэше, выдает ошибку, но ошибка не определена.

Я создал контроллер для создания и управления подключением:

 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;
 

Это работает для установления соединения.

Однако при попытке получить результат из метода hgetall выводится пустая ошибка.

 /**
 * 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;
}
 

Возникает ошибка, но ошибка не определена. Блок «поймать» redisClient.hgetall(lookupKey) строки вызывается, но ошибка не определена.

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

Вопросы: Как я могу устранить эту проблему? Как я могу увидеть подробную информацию об ошибке, которая возникает?

Комментарии:

1. Вы отследили в отладчике, где именно в библиотеке возникает ошибка?

2. Какова ваша версия сервера redis?

3. Можете ли вы подключиться к серверу redis с помощью «redis-cli», а затем выполнить оттуда ту же команду? Я хочу убедиться, что сохраненное значение на самом деле является «хэшем», а не чем-то другим, например «списком» или «набором» и т. Д.

4. @SuyashGaur спасибо, на самом деле это был НЕ хэш, и поэтому команда hgetall не работала. Я изменил его на .get, и это сработало. Я думаю, проблема в том, что сообщение об ошибке было неопределенным, поэтому я был сбит с толку, я думаю, что оно может где-то потеряться, но я должен быть в состоянии продолжить сейчас. Большое вам спасибо!

Ответ №1:

Как указано в комментариях выше,
функция hgetall() не работает, поскольку тип данных, соответствующий lookup значению, отсутствовал hash .

Изменение его на get() исправило проблему.