From 8e5c84f7edcda85a6f7e36c04ebd74152c1cade1 Mon Sep 17 00:00:00 2001 From: Damien Arrachequesne Date: Tue, 30 Nov 2021 00:25:46 +0100 Subject: [PATCH] feat: do not emit "error" events anymore 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: - https://github.com/socketio/socket.io-redis-adapter/issues/412 - https://github.com/socketio/socket.io-redis-adapter/issues/425 --- lib/index.ts | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/lib/index.ts b/lib/index.ts index efa71c4..99c4cd8 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -114,12 +114,6 @@ export class RedisAdapter extends Adapter { this.responseChannel = prefix + "-response#" + this.nsp.name + "#"; const specificResponseChannel = this.responseChannel + this.uid + "#"; - const onError = (err) => { - if (err) { - this.emit("error", err); - } - }; - const isRedisV4 = typeof this.pubClient.pSubscribe === "function"; if (isRedisV4) { this.subClient.pSubscribe( @@ -136,18 +130,27 @@ export class RedisAdapter extends Adapter { } ); } else { - this.subClient.psubscribe(this.channel + "*", onError); + this.subClient.psubscribe(this.channel + "*"); this.subClient.on("pmessageBuffer", this.onmessage.bind(this)); - this.subClient.subscribe( - [this.requestChannel, this.responseChannel, specificResponseChannel], - onError - ); + this.subClient.subscribe([ + this.requestChannel, + this.responseChannel, + specificResponseChannel, + ]); this.subClient.on("messageBuffer", this.onrequest.bind(this)); } - this.pubClient.on("error", onError); - this.subClient.on("error", onError); + const registerFriendlyErrorHandler = (redisClient) => { + redisClient.on("error", () => { + if (redisClient.listenerCount("error") === 1) { + console.warn("missing 'error' handler on this Redis client"); + } + }); + }; + + registerFriendlyErrorHandler(this.pubClient); + registerFriendlyErrorHandler(this.subClient); } /** @@ -211,7 +214,7 @@ export class RedisAdapter extends Adapter { try { request = JSON.parse(msg); } catch (err) { - this.emit("error", err); + debug("ignoring malformed request"); return; } @@ -406,7 +409,7 @@ export class RedisAdapter extends Adapter { try { response = JSON.parse(msg); } catch (err) { - this.emit("error", err); + debug("ignoring malformed response"); return; }