已配置错误处理仍触发Redis客户端缺少error处理器提示问题
问题:Redis客户端报错"missing 'error' handler on this Redis client"排查
我正在整合Redis、@socket.io/redis-adapter、Socket.IO与express-session,使用的依赖版本如下:
{ "express": "^4.17.1", "express-session": "^1.17.1", "redis": "^4.5.1", "socket.io": "^4.5.4", "socket.io-client": "^4.5.4", "@socket.io/redis-adapter": "^8.0.1" }
相关实现代码如下:
// Promisify the methods so we can use async / await with redis bluebird.promisifyAll(redis); const redisClient = redis.createClient({ legacyMode: true }); const subClient = redisClient.duplicate({ legacyMode: true }); bluebird.promisifyAll(redisClient); bluebird.promisifyAll(subClient); const redisStore = new RedisStore({ client: redisClient }); // Applying Redis middleware app.use( session({ secret: process.env.SESSION_SECRET, // create new redis store. store: redisStore, cookie: { secure: !isDevEnv, // if true: only transmit cookie over https httpOnly: true, // if true: prevents client side JS from reading the cookie maxAge: 30 * 24 * 60 * 60 * 1000, // session max age in milliseconds }, resave: false, saveUninitialized: true, rolling: true, }), ); // Start the server const server = app.listen(PORT, console.log(`App listening on port: ${PORT}`)); server.setTimeout(6 * 60 * 1000); // Start socket io with cors enabled const io = new Server(); io.adapter(adapter.createAdapter(redisClient, subClient)); (async () => { Promise.allSettled([redisClient.connect(), subClient.connect()]).then(() => { io.listen(server, { cors: { origin: [ 'http://localhost:3000' ], }, transports: ['websocket'], }); identityCheck.init(io, redisClient); // using redisClient in other file where we use redis get, set methods redisClient.on('error', (error) => console.error('error from redisClient', error)); subClient.on('error', (error) => console.error('error from subClient', error)); }); })();
我已为redisClient和subClient添加了error事件处理器,但仍收到提示“missing 'error' handler on this Redis client”,请问哪里操作有误?
问题原因与解决方法
问题核心是error事件处理器绑定时机太晚。你把事件监听放在了connect()的Promise回调里,但Redis客户端在调用connect()之前、或者连接过程中就可能抛出错误(比如地址错误、认证失败),此时还未绑定处理器,就会触发警告。
修改方案
将error事件监听提前到创建客户端之后、调用connect()之前的位置,确保所有阶段的错误都能被捕获:
// Promisify the methods so we can use async / await with redis bluebird.promisifyAll(redis); const redisClient = redis.createClient({ legacyMode: true }); const subClient = redisClient.duplicate({ legacyMode: true }); // 提前绑定error事件处理器,覆盖客户端生命周期全阶段 redisClient.on('error', (error) => console.error('error from redisClient', error)); subClient.on('error', (error) => console.error('error from subClient', error)); bluebird.promisifyAll(redisClient); bluebird.promisifyAll(subClient); const redisStore = new RedisStore({ client: redisClient }); // ... 中间其他代码保持不变 (async () => { await Promise.allSettled([redisClient.connect(), subClient.connect()]); io.listen(server, { cors: { origin: ['http://localhost:3000'], }, transports: ['websocket'], }); identityCheck.init(io, redisClient); })();
额外说明
- 用
await替代.then()可以让async/await风格的代码更简洁,避免嵌套回调。 - Redis v4版本本身支持Promise API,若后续重构可以考虑去掉bluebird的promisify,直接使用官方异步方法,减少依赖。
内容的提问来源于stack exchange,提问作者reciever
相关产品推荐
相关产品推荐

