NestJS委托业务至子文件后Exception Filter失效问题
NestJS Gateway 移业务逻辑到服务后异常过滤器失效的解决办法
问题核心
把WebSocket事件的业务逻辑从Gateway移到ChatService后,Gateway上配置的MyCustomExceptionsFilter无法再捕获异常,手动捕获异常也没法把错误返回给前端,终端会直接抛出未处理的错误。
解决方案
1. 确保Gateway订阅方法正确await服务调用
原来的Gateway方法没有await服务的异步调用,导致异步异常变成未捕获的Promise拒绝,过滤器无法感知到异常。修改Gateway代码:
@SubscribeMessage('createRoom') async createRoom(client: Socket, channel: newChannelDto) { // 加上await,让异常能冒泡到Gateway的执行上下文 await this.chatService.createRoom(client, channel); }
2. 在服务中直接处理异常并返回给客户端
如果不想依赖Gateway的过滤器,可在ChatService中捕获异常后,通过Socket直接给客户端发送错误事件:
async createRoom(client: Socket, channel: newChannelDto) { try { await this.channelService.createChannel(channel.chanName, client.data.user, channel.password, channel.private); client.join(channel.chanName); for (let [allUsers, socket] of this.gateway.activeUsers.entries()) { this.gateway._server.to(socket.id).emit('rooms', " get rooms ", await this.channelService.getChannelsForUser(allUsers)); } } catch (error) { // 给当前客户端发送自定义错误事件 client.emit('error', { message: error instanceof Error ? error.message : '创建房间失败' }); // 若仍需Gateway过滤器处理,可继续抛出异常(前提是Gateway方法已await) throw error; } }
3. 检查自定义过滤器是否支持WebSocket上下文
确认MyCustomExceptionsFilter能正确处理WebSocket的执行上下文,而非只支持HTTP。示例调整:
@Catch() export class MyCustomExceptionsFilter implements ExceptionFilter { catch(exception: unknown, host: ArgumentsHost) { // 判断是否为WebSocket上下文 if (host.getType() === 'ws') { const client = host.switchToWs().getClient<Socket>(); const errorMsg = exception instanceof Error ? exception.message : '未知错误'; client.emit('error', { message: errorMsg }); return; } // 保留原HTTP上下文处理逻辑 // ... } }
内容的提问来源于stack exchange,提问作者digicolp
相关产品推荐
相关产品推荐

