node-redis: Redis hangs indefinitely on connection lost
Here is my code sample:
const redis = require('redis');
const client = redis.createClient({
url: '127.0.0.1',
password: 'password',
disableOfflineQueue: true,
socket: {
timeout: 1000,
connectTimeout: 1000,
tls: true
},
});
client.on('error', (err) => console.log('Redis Client Error', err));
// Connection is on here
client.connect().then(async () => {
// I disconnect the network here and expected to get an error and handle it
const value = await client.get('key'); // <--- application hangs here
// this code has never been executed
await client.quit();
console.log(value);
}).catch(err => console.log(err));
My application hangs indefinitely if connection lost for some reasons and I want to handle this case. I try to catch every possible errors but it doesn’t help - application hangs on get() method and nothing happens.
So I just need to handle redis error on lost connection to be able to log this error and move next in my code.
Environment:
- Node.js Version: v16.13.0
- Redis Server Version: 6.0.5
- Node Redis Version: 4.2.0
- Platform: Unknown
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 6
- Comments: 24
Commits related to this issue
- fix #2205 - reject commands in connect phase when `disableOfflineQueue` is `true` — committed to leibale/node-redis by leibale 2 years ago
- fix #2205 - reject commands in connect phase when `disableOfflineQueue` is `true` (#2328) — committed to redis/node-redis by leibale 2 years ago
Thanks for your help, @leibale!
Just in case someone else needs this, what solved my problem was basically some changes to the client code, as below:
Some pointers of what changed:
disableOfflineQueue: true, as suggested by @leibale before_client.on()part)awaitwhen connecting to the server on_client.connect()With those changes, now my application keeps retrying to reconnect with the server when the latter is offline and is able to default to the S3 storage after the timeout set on the
reconnectStrategyparam (without hanging too, which is great!).Cheers guys! Thanks again!
A little late to say that, but thanks! ^^
@GledsonAfonso thanks for summarizing it 😃
just one note, I would suggest using the default
reconnectStrategyinstead of passing a custom one (retries => Math.min(retries * 50, 500))Thanks for the reply and sorry for my late reply, I just manage to test this today. It didn’t work, though. Here’s the code from my Redis client:
The way I’m testing this is through Docker Compose. I’m starting the Redis server along with an API that needs to connect to it and then I disconnect the Redis server and watch the logs from the API. When this happens, it fails and the application is successfully closed, but when I start it without starting the Redis server first, it gives me this log:
And the API doesn’t fail, allowing the application to hang infinitely whenever some data are requested.
What I needed was that the application to throw some error when data are requested, instead of just hanging like that. I need this because the API needs to redirect the request to S3 storage whenever this problem happens.
An alternative is to inject the redis client, HOWEVER, you need to use the redis version 3.x.x, if you use version 4.x.x the library never resolves the promises because the callbacks are never called. I must admit this is very annonying