Handling connection errors - redis
skinofstars opened this issue · comments
Hi, I'm having trouble figuring out how to add handle connection errors. This is with a view to having a fallback when there is a connection error.
I'm trying somehting along the lines of this
let hasStore;
const store = new KeyvRedis(options.redisUri);
store.on('connect', () => (hasStore = true));
store.on('error', () => (hasStore = false));
But all I'm getting is the following, before I get a chance to do anything with hasStore
throw er; // Unhandled 'error' event
^
Error: connect ECONNREFUSED 127.0.0.1:6379
Any guidance appreciated
Hello, check redis/ioredis#1241 🙂
Ok, I think I'd written my problem wrong, or gone too far down the wrong solution route.
When you use IORedis directly, if the connection fails then you can use a try/catch block. With this module, an error event is emitted. How can I handle a failed connection?
Here is a code example, which when a Redis instance is unreachable, with IORedis it falls back to the database conection.
import Keyv from '@keyvhq/core';
import KeyvRedis from '@keyvhq/redis';
import {debug} from '../handlers/util.debug.js';
import Redis from 'ioredis';
/**
* Add .cache() to any knex query to make is cachable
*/
export function cacheable(
knex,
options = {redisUri: 'redis://localhost:6379', namespace: 'cache'}
) {
/** Using Keyv */
// const keyv = new Keyv({
// store: new KeyvRedis(options.redisUri),
// namespace: options.namespace,
// });
/** Using IORedis */
const redis = new Redis(options.redisUri, {
keyPrefix: `${options.namespace}:`,
});
// https://github.com/knex/knex/issues/2787#issuecomment-530780656=
knex.QueryBuilder.extend('cache', async function () {
try {
const cacheKey = this.toString();
debug('Cache key: ' + JSON.stringify(cacheKey));
// const cacheVal = await keyv.get(cacheKey);
const cacheVal = await redis.get(cacheKey).then((res) => JSON.parse(res));
if (cacheVal) {
return cacheVal;
}
const data = await this;
// await keyv.set(cacheKey, data);
await redis.set(cacheKey, JSON.stringify(data));
return data;
} catch (e) {
debug(e);
return this;
}
});
return knex;
}
However, using the Keyv library (as commented out in the above code sample), but with an unreachable Redis server, we get the following
node:events:505
throw er; // Unhandled 'error' event
^
Error: connect ECONNREFUSED 127.0.0.1:6379
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1187:16)
Emitted 'error' event on Keyv instance at:
at KeyvRedis.<anonymous> (/Volumes/projects/whotargetsme/wtm-rawlog-parser/node_modules/@keyvhq/core/src/index.js:20:44)
at KeyvRedis.emit (node:events:527:28)
at KeyvRedis.emit (node:domain:475:12)
at EventEmitter.<anonymous> (/Volumes/projects/whotargetsme/wtm-rawlog-parser/node_modules/@keyvhq/redis/src/index.js:26:14)
at EventEmitter.emit (node:events:527:28)
at EventEmitter.emit (node:domain:475:12)
at EventEmitter.silentEmit (/Volumes/projects/whotargetsme/wtm-rawlog-parser/node_modules/ioredis/built/Redis.js:447:30)
at Socket.<anonymous> (/Volumes/projects/whotargetsme/wtm-rawlog-parser/node_modules/ioredis/built/redis/event_handler.js:189:14)
at Object.onceWrapper (node:events:642:26)
at Socket.emit (node:events:539:35) {
errno: -61,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 6379
}