node-redis: Error, which is returned from retry_strategy remains uncaught
I have the code below and try to imitate dropped connection using iptables -A OUTPUT -p tcp --dport 6379 -j REJECT.
self.client = redis.createClient(self.cfg.port, self.cfg.host, {
retry_strategy: function (options) {
console.log('retry strategy check');
console.log(options);
if (options.error) {
if (options.error.code === 'ECONNREFUSED') {
// End reconnecting on a specific error and flush all commands with a individual error
return new Error('The server refused the connection');
}
if (options.error.code === 'ECONNRESET') {
return new Error('The server reset the connection');
}
if (options.error.code === 'ETIMEDOUT') {
return new Error('The server timeouted the connection');
}
}
if (options.total_retry_time > 1000 * 60 * 60) {
// End reconnecting after a specific timeout and flush all commands with a individual error
return new Error('Retry time exhausted');
}
if (options.attempt > 5) {
// End reconnecting with built in error
return new Error('Retry attempts ended');
}
// reconnect after
return 1000;
}
});
self.client.on('ready', function () {
log.trace('Redis client: ready');
});
self.client.on('connect', function () {
log.trace('Redis client: connect');
});
self.client.on('reconnecting', function () {
log.trace('Redis client: reconnecting');
});
self.client.on('error', function (err) {
log.error({err: err}, 'Listener.redis.client error: %s', err);
process.exit(1);
});
self.client.on('end', function () {
log.trace('Redis client: end');
});
self.client.on('warning', function () {
log.trace('Redis client: warning');
});
It is supposed that all redis errors are emitted in error event. But here is what i’ve got in console output:
21:00:14.666Z TRACE script: Redis client: connect 21:00:14.695Z TRACE script: Redis client: ready 21:10:23.837Z TRACE script: Redis client: end retry strategy check { attempt: 1, error: { [Error: Redis connection to redis.callision.info:6379 failed - read ECONNRESET] code: ‘ECONNRESET’, errno: ‘ECONNRESET’, syscall: ‘read’ }, total_retry_time: 0, times_connected: 1 }
/node_modules/q/q.js:155 throw e; ^ AbortError: Stream connection ended and command aborted. It might have been processed. at RedisClient.flush_and_error (/node_modules/redis/index.js:350:23) at RedisClient.connection_gone (/node_modules/redis/index.js:612:18) at RedisClient.on_error (/node_modules/redis/index.js:398:10) at Socket.<anonymous> (/node_modules/redis/index.js:272:14) at emitOne (events.js:90:13) at Socket.emit (events.js:182:7) at emitErrorNT (net.js:1255:8) at nextTickCallbackWith2Args (node.js:474:9) at process._tickCallback (node.js:388:17)
And as a question: Why it takes about 10 minutes to detect that connection is gone? Is there any way to raise an error in case of no response within 10 seconds? May be any option like response_timeout etc.
- Version: node_redis v.2.6.5 and Redis 3.0.7
- Platform: Node.js v5.5.0 on Ubuntu 14.04.4 LTS
- Description: error from retry_strategy remains uncaught
About this issue
- Original URL
- State: open
- Created 7 years ago
- Reactions: 21
- Comments: 23 (2 by maintainers)
Any news ? I have the same problem.
I am encountering the same error. If I intentionally provide Redis client a bad URL, the on.error method is not invoked. Here is a simple example:
Same here. This nasty hack seems to create the expected behaviour, but not sure if it has any wider implications:
I too am not able to catch errors when receiving an
ENOTFOUND.with:
Debugging the application, i’m getting into the
ENOTFOUNDcheck as noted above in theretry_strategybut it’s not invoking the error event handler.This caught me out today as well. From looking at the code briefly, this seems to be intentional behaviour. https://github.com/NodeRedis/node_redis/blob/79558c524ff783000a6027fb159739770f98b10e/index.js#L405 explicitly states that if
retry_strategyis set, not to emit the error and instead continues to throw it. I’d be curious to hear why this is the case though, there doesn’t seem to be a reason why it can’t emit it instead of throwing from a quick look. Is there any reason this conditional couldn’t be taken out, so that the error will always be emitted?We switched our implementation to https://github.com/luin/ioredis instead, which brought a few improvements (native Promises, lazyConnect(avoid opening a connection when instanciating the redis client, helped us handle errors exactly where we needed)), and allows the following code to run:
Using the following
utils/redis.js:And
utils/redis.test.jsfile:Env variables:
Any news?
@v1adko I’m currently traveling, but I’ll try to take a look at it later today or tomorrow (unless Ruben beats me to it).