-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SocketClosedUnexpectedlyError - Unhandled Error #2624
Comments
"Unhandled 'error' event" means that you are not listening to 'error's... maybe you have more than one client in the code and you forgot to listen to errors on one of them? |
I am having this problem too. I only have one client, and the on error is set. But it crashes anyways. Using 4.6.10 on node 20.7.0 this.client = createClient()
this.client.on('error', err => console.log('Redis Client Error', err))
this.client.on('end', () => {
console.log('Redis connection ended');
})
After tracing it, I think the error ultimately comes from something in your code making a get or set to redis while it is down. |
I confirm I have only 1 client and I set the error handler.
Thanks, |
In my case, it is not catch inside the error handler :( If I shutdown the redis server, the error is properly managed: @leibale |
How to fix this? |
If its like my solution, double check you are not trying to set or get while the connection is down. Add a global variable for yourself to check that updates let alive=false
_redisClient.on('end', () => {
alive=false
});
_redisClient.on('ready', () => {
alive=true
});
_redisClient.on('error', (err) => {
alive=false
}); and before redisClient.set() if (alive){
redisClient.set(etc, etc2)
} That way you don't try to set when its dead. I made a whole wrapper class around redis so it was trivial to add a check to all of them |
damn, same erro. there's no fix i see |
@TDola you can use @ap0sentada @bossajie @elvince |
You can use this code to reproduce the problem. package.json {
"name": "redis-crash-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"run": "node index.js"
},
"type": "module",
"author": "",
"license": "ISC",
"dependencies": {
"redis": "^4.6.10"
}
}
import { createClient } from 'redis'
const client = createClient()
client.on('error', async err => {
console.log('Redis Client Error', err)
})
client.on('end', () => {
console.log('Redis connection ended');
})
client.on('ready', () => {
console.log('redis connected')
})
await client.connect()
const createKeys = () => {
for (let i = 0; i < 10000; i++) {
const value = JSON.stringify({test: i}, null, 2)
// purposely no await to simulate a busy async system
client.set('test-key:' + performance.now(), value)
}
}
const removeKeys = async () => {
const results = await client.keys('test-key:*')
for (const key of results) {
// no await on purpose
client.del(key)
}
}
const runner=()=>{
console.log('starting runner loop')
createKeys()
console.log('done setting keys')
removeKeys()
console.log('done deleting keys, waiting 1000')
setTimeout(()=>{runner()}, 1000)
}
process.on('SIGINT', async function() {
console.log("Caught interrupt signal");
const results = await client.keys('test-key:*')
for (const key of results) {
await client.del(key)
}
console.log("test keys cleaned")
process.exit()
})
runner() leave it to run a little bit, like 10 seconds. Then shut down your redis manually, the script should crash most of the time. Fiddle with the timeout to adjust.
The real bug might be that the ready event kept getting called even though the redis server was still down. What was it connecting to? |
@TDola its fine not awaiting a promise, but you'll have to catch the errors, otherwise it'll crash with "unhandled promise rejection" error.. I tried reproducing it using import { createClient } from 'redis';
const client = await createClient()
.on('error', (err) => console.log('client error', err))
.on('ready', () => console.log('client is ready'))
.connect();
function createKeys() {
for (let i = 0; i < 10000; i++) {
client.set(`text-key${i.toString()}`, i.toString()).catch(err => {
console.error(`Error in SET ${i}`, err);
});
}
}
async function removeKeys() {
for (const key of await client.keys('test-key:*')) {
client.del(key).catch(err => {
console.error(`Error in DEL ${key}`, err);
});
}
}
function runner() {
console.log('starting runner loop');
createKeys();
console.log('done setting keys');
removeKeys();
console.log('done deleting keys, waiting 1000');
setTimeout(runner, 1000);
}
runner(); but... it works... |
Your key set is using a number as the ID instead of test-key: so it won't find anything in the key search. I haven't had much coffee yet so I could be wrong in reading that. But if the catch solves it, then perfect that's easily implementable. function createKeys() {
for (let i = 0; i < 10000; i++) {
client.set(i.toString(), i.toString()).catch(err => {
console.error(`Error in SET ${i}`, err);
});
}
} |
We are using createCluster(). Maybe the issue is coming from createCluster() ? |
@leibale On TDola case, it was reproductible and you fix it by reviewing the code sample. If I properly understand, the issue can arise on promise not awaited / catched, correct? thanks Edit: I checked and all calls are awaited. I hope we can have a way to track this kind of bugs.
|
The application(nest.js) is hosted on render, and this error is often reported. Redis uses the vercel kv service. CacheModule.registerAsync({
isGlobal: true,
useFactory: async () => {
const store = await redisStore({
socket: {
host: process.env.KV_HOST,
port: +process.env.KV_PORT,
tls: true,
},
username: process.env.KV_USERNAME,
password: process.env.KV_PASSWORD,
ttl: 60,
})
return {
store: store as unknown as CacheStore,
}
},
}),
ThrottlerModule.forRootAsync({
useFactory: () => ({
throttlers: [{ limit: 10, ttl: seconds(60) }],
storage: new ThrottlerStorageRedisService({
host: process.env.KV_HOST,
port: +process.env.KV_PORT,
username: process.env.KV_USERNAME,
password: process.env.KV_PASSWORD,
tls: true,
maxRetriesPerRequest: 20,
} as unknown as RedisOptions),
}),
}),
EDIT
|
I am using docker to run Redis and as client, I am using node-redis. when I am executing my code I am getting
what is wrong in the code and how should we fix it ? |
I've been having the same/similar issue. In my case I'm using The symptoms are that after a few minutes, Node.js will predictably crash with an unhandled Interestingly, the crashes are occasionally V8 heap-allocation-related, rather than an uncaught exception. So something weird definitely seems to be happening on the socket-close condition. Could it possibly be an infinite recursive loop trying to reconnect? At first, nothing I tried seemed to fix the issue, until I changed the client idle timeout setting from |
FIX : |
I'm having the same issue |
Hello @TDola I implemented my redisClient class this way as you suggested. Here is the class definition.
But this keeps the "Socket unexpectedly closed" error and also introduces a new error saying "cannot read properties of undefined (reading hSet)" which I think indicates that my client is undefined at a point of time. |
What you have looks pretty much the same as how I implemented it. So it might be just when you are calling it. If you are accidentally calling your sets before you have time to construct your class and wait for the connect to finish. Also, the catches were unexpectedly important, as shown in the response to my question here |
I had the same error message emitting every couple millisecond. |
Description
Hi,
We are experiencing issue with the client. Many times a day we have this unhandled error that is thrown away from the redis client.
We have properly set the "Error" handler but it is not catched in it. As a consequence our process is crashing multiple times per day.
It is severly impacting our customers.
We already dig into the issue list where this error was mentionned, we tried the PingInterval / SetInterval stuff as we are on Azure but it doesn't fix the issue.
I suspect this is another edge case than the load balancer that drop the connection.
If you can see how to catch properly this error so the reconnect system can reopen smoothlty the connection it will save our day.
Thanks,
Node.js Version
Node.js v18.17.1
Redis Server Version
Node.js v18.17.1
Node Redis Version
No response
Platform
Linux
Logs
The text was updated successfully, but these errors were encountered: