React Socket客户端如何捕获NestJS后端WebSocket验证错误
NestJS + Socket.io 前端捕获验证错误方案
后端配置(NestJS)
1. 配置ValidationPipe抛出WebSocket异常
修改@UsePipes配置,把class-validator的验证错误包装为WsException,让后端能通过WebSocket传递错误信息:
@UsePipes(new ValidationPipe({ exceptionFactory: (validationErrors) => { const formattedErrors = validationErrors.map(err => ({ field: err.property, messages: Object.values(err.constraints || {}) })); return new WsException({ type: 'validation_error', errors: formattedErrors }); }, whitelist: true, transform: true })) @SubscribeMessage("createMessage") handleCreate( @MessageBody() messageInput: MessageInput, @MessageAck() ack: (error?: any, data?: any) => void ): void { // 验证通过后执行业务逻辑 console.log(messageInput); // 调用ack返回成功响应 ack(null, { data: "Hello world" }); }
2. 实现WebSocket异常过滤器
创建过滤器捕获WsException,并通过Socket.io的确认机制(ack)把错误返回给前端:
import { ExceptionFilter, Catch, ArgumentsHost, WsException } from '@nestjs/common'; import { WsArgumentsHost } from '@nestjs/websockets'; @Catch(WsException) export class WsValidationFilter implements ExceptionFilter { catch(exception: WsException, host: ArgumentsHost) { const wsHost = host.switchToWs() as WsArgumentsHost; const ack = wsHost.getArgByIndex(2); if (typeof ack === 'function') { ack(exception.getError()); } } }
3. 网关应用过滤器
在WebSocket网关类上启用过滤器:
@WebSocketGateway() @UseFilters(WsValidationFilter) export class ChatGateway { // ... 网关其他逻辑 }
前端修改(React + Socket.io)
使用Socket.io的确认回调机制,在发送事件时传入回调函数,直接捕获后端返回的错误:
import { useEffect, useState } from 'react'; import io from 'socket.io-client'; const ChatComponent = () => { const [socket, setSocket] = useState(null); useEffect(() => { const newSocket = io('http://localhost:3000'); // 替换为你的后端地址 setSocket(newSocket); return () => newSocket.close(); }, []); const sendInvalidMessage = () => { const invalidMessage = { conversation: "Some Data" // 不符合验证规则的数据 }; socket.emit('createMessage', invalidMessage, (error, response) => { if (error) { console.log('验证失败:', error); // 展示错误给用户 alert(`验证错误:${error.errors.map(e => `${e.field}: ${e.messages.join(', ')}`).join('\n')}`); return; } console.log('发送成功:', response); }); }; return ( <button onClick={sendInvalidMessage}>发送不符合规则的消息</button> ); }; export default ChatComponent;
替代方案:监听全局错误事件
如果不需要针对单个事件的精准回调,可以监听Socket.io的全局error事件,但会捕获所有WebSocket级别的错误:
socket.on('error', (error) => { console.log('全局WebSocket错误:', error); });
内容的提问来源于stack exchange,提问作者Jannat
相关产品推荐
相关产品推荐

