Skip to content
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

Unable to catch ECONNRESET error and it is causing app to crash. #412

Closed
daveteu opened this issue Jul 19, 2021 · 4 comments
Closed

Unable to catch ECONNRESET error and it is causing app to crash. #412

daveteu opened this issue Jul 19, 2021 · 4 comments

Comments

@daveteu
Copy link

daveteu commented Jul 19, 2021

I need some help as your documentation on Client Error handling seems to be gone.

I've searched through forums and issues here. I've followed the recommended actions as follows. However, I'm still not able to catch the errors below, and it's causing my app to crash. My redis servers are all well and not disconnected at that time as I have other services using same server.

Can anyone provide me with some directions?

"@socket.io/redis-adapter": "^7.0.0",
"@socket.io/redis-emitter": "^4.1.0",

Catching error for both sub and pub client - Done ✅

pubClient.on("error", (err) => {
	debug(`REDIS ADAPTOR DISCONNECTED ON pubClient %O`, err)
})
subClient.on("error", (err) => {
	debug(`REDIS ADAPTOR DISCONNECTED ON subClient %O`, err)
})

Catch error on adapter - Done ✅

io.of('/').adapter.on('error', function(error){

	debug('error: ', error);
	
});

Ping to keep connection alive - Done ✅

setInterval(() => {
	// emitter.of('/user').emit("time", new Date);
	io.of('/user').emit("time", new Date())
  }, 300000);

I've also tried using both node-redis and ioredis and both end up with same error below Done ✅

Manage to catch this with redis on error event ✅

 socket REDIS ADAPTOR DISCONNECTED ON pubClient Error: read ECONNRESET
  socket     at TCP.onStreamRead (internal/stream_base_commons.js:209:20) {
  socket   errno: -54,
  socket   code: 'ECONNRESET',
  socket   syscall: 'read'
  socket } +5h
  socket error:  Error: read ECONNRESET
    at TCP.onStreamRead (internal/stream_base_commons.js:209:20) {
  errno: -54,
  code: 'ECONNRESET',
  syscall: 'read'
} +0ms

Unable to catch this event ❌❌❌

I think this causes my app to crash


events.js:292
      throw er; // Unhandled 'error' event
      ^

Error: read ECONNRESET
    at TCP.onStreamRead (internal/stream_base_commons.js:209:20)
Emitted 'error' event on RedisAdapter instance at:
    at Redis.onError (/Users/Myname/Work/expressjs/api.singa.sg/node_modules/@socket.io/redis-adapter/dist/index.js:61:22)
    at Redis.emit (events.js:327:22)
    at Redis.EventEmitter.emit (domain.js:486:12)
    at Redis.silentEmit (/Users/Myname/Work/expressjs/api.singa.sg/node_modules/ioredis/built/redis/index.js:544:26)
    at Socket.<anonymous> (/Users/Myname/Work/expressjs/api.singa.sg/node_modules/ioredis/built/redis/event_handler.js:190:14)
    at Object.onceWrapper (events.js:422:26)
    at Socket.emit (events.js:327:22)
    at Socket.EventEmitter.emit (domain.js:486:12)
    at emitErrorNT (internal/streams/destroy.js:106:8)
    at emitErrorCloseNT (internal/streams/destroy.js:74:3)
    at processTicksAndRejections (internal/process/task_queues.js:80:21) {
  errno: -54,
  code: 'ECONNRESET',
  syscall: 'read'
}
@vincesempre
Copy link

Hi!
I had a similar issue and I resolved it by adding an error listener on each namespace.

Something like:

const namespaces = io.nsps;
Object.keys(namespaces).forEach((namespaceName) => {
  io.of(namespaceName).adapter.on('error', (e) => {
  console.error(`On namespace: ${namespaceName} - ${e}`);
  });
});

Hope this helps!
M.

@daveteu
Copy link
Author

daveteu commented Aug 11, 2021

Hi!
I had a similar issue and I resolved it by adding an error listener on each namespace.

Something like:

const namespaces = io.nsps;
Object.keys(namespaces).forEach((namespaceName) => {
  io.of(namespaceName).adapter.on('error', (e) => {
  console.error(`On namespace: ${namespaceName} - ${e}`);
  });
});

Hope this helps!
M.

Thank you but why is my io.nsps undefined?

darrachequesne added a commit that referenced this issue Nov 29, 2021
Previously, the "error" events from the two Redis clients were
forwarded by each instance of the adapter, which made it quite hard to
handle the errors with a lot of namespaces (as there is one instance of
adapter per namespace).

```js
io.of("/my-namespace").adapter.on("error", () => {
  // ...
});
```

The adapter instance will no longer emit "error" events, and will print
a warning if there is no other error handler registered (for backward
compatibility).

The error handling must be done directly on the Redis client:

```js
redisClient.on("error", (err) => {
  // something went wrong, maybe the connection to the server was lost
});
```

Related:

- #412
- #425
@darrachequesne
Copy link
Member

For future readers:

This should be fixed by 8e5c84f, included in release 7.1.0: https://github.com/socketio/socket.io-redis-adapter/releases/tag/7.1.0

@gollobo
Copy link

gollobo commented Sep 29, 2023

Hello, I'm still experiencing the same issue. I've tried with various Redis hosts in case that was the problem. I've also tried using both redis-node and ioredis, but it doesn't seem to work either. I've tried with TLS and without TLS. I'm a bit desperate because the error randomly restarts my Node.js server a couple of times a day. I've tried the following solutions:

Catch the error with:

pubClient.on("error", function(err){ console.log(err)});
server.listen(process.env.PORT || 3000, () => {
 //logic here
}).on('error', function (err) {
    console.log(err);
});
process.on('uncaughtException', function (err) {
    console.log(err.stack)
});
io.of('/').adapter.on('error', function (error) {
  console.log('error: ', error);
});

None of these solutions catch the error. Obviously, if I remove Redis and the adapter, it stops happening. Thank you very much for your help.

My code to start the server:

const http = require("http");
const express = require('express')
const app = express()
app.use(express.json({ limit: '1mb' }))
const server = http.createServer(app);
const { Server } = require("socket.io");
const { createAdapter } = require('@socket.io/redis-adapter');
const Redis = require('ioredis');

const pubClient = new Redis("Redis_url_here");
const subClient = pubClient.duplicate();

pubClient.on("error", logError);

subClient.on("error", logError);

const io = new Server(server);

io.adapter(createAdapter(pubClient, subClient));
server.listen(process.env.PORT || 3000, () => {
  if (process.send) process.send('ready');
  console.log('listening on port');
}).on('error', function (err) {
    console.log(err);
});

With this code the server works well and all the cluster are correctly connected via redis, but randomly have the crash ´read ECONNRESET´ :(

ioredis version: 5.3.2
redis version: 4.6.10
adapter version: 8.2.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants