You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Note this issue is similar to #1077, #1157, & #1102 . I'm opening a new ticket since I want to focus on the primary issue here which is the Unhandled error event" portion. Take the following code:
constRedis=require("ioredis");asyncfunctionsleep(ms){returnnewPromise((resolve)=>setTimeout(resolve,ms));}asyncfunctionmain(){letredis;try{redis=newRedis('redis://localhost:6379/');while(true){constinfo=awaitredis.info('Server');console.log(`Server Info at ${newDate()}:\n${info}`);awaitsleep(3000);}}catch(err){console.error('Caught Error: ',err);}finally{awaitredis.disconnect();}}main();
And follow the steps below:
Ensure Redis is running locally
Start the demo app
Wait for demo app to connect and start displaying server details
Now an error being thrown here is reasonable as the Redis server is not available. The problem is that these are unhandled errors. This is very not good as it implies that these errors are being thrown before an "error" event handler can be registered on the socket. In our code base we listen for unhandled errors and begin a shutdown if they are encountered. Something like this:
So it appears that an error event is being thrown before ioredis attaches its error handler to catch it. From reading the code I believe this error is happening before eventHandler.errorHandler is attached to the socket during the reconnect attempt in built/redis/index.js in the connect method.
Let me know if clarification is needed:
node: 12.18.3
ioredis: 4.17.3
The text was updated successfully, but these errors were encountered:
So my initial theory was quite wrong. The error handler is being attached to the socket as expected. Where things fall apart is in the silentEmit method prototype. In that method several checks happen, mainly to see if there are listeners. If there are then the event goes to the listener. But if there isn't then the error event is logged and then false is returned. The false being returned indicates to the previous emitter that there were no emitters that handled it. And in the case of an error event (which is a special event type of course) that means the error event will become an uncaughtException as per node event rules. This explains why I am seeing this behavior.
However, ioredis emits all error events silently (only emits when there's at least one listener) so that your application won't crash if you're not listening to the error event.
So... what is the behavior supposed to be? Is the code wrong or are the documents wrong?
Note this issue is similar to #1077, #1157, & #1102 . I'm opening a new ticket since I want to focus on the primary issue here which is the Unhandled error event" portion. Take the following code:
And follow the steps below:
Now an error being thrown here is reasonable as the Redis server is not available. The problem is that these are unhandled errors. This is very not good as it implies that these errors are being thrown before an "error" event handler can be registered on the socket. In our code base we listen for unhandled errors and begin a shutdown if they are encountered. Something like this:
So it appears that an error event is being thrown before ioredis attaches its error handler to catch it. From reading the code I believe this error is happening before
eventHandler.errorHandler
is attached to the socket during the reconnect attempt inbuilt/redis/index.js
in theconnect
method.Let me know if clarification is needed:
node: 12.18.3
ioredis: 4.17.3
The text was updated successfully, but these errors were encountered: