如何在NestJS Gateway Socket.io中捕获验证错误信息
问题
我用ValidationPipe校验用户发送的JSON数据合法性,校验器本身工作正常,但没法捕获错误并返回给客户端。我知道ValidationPipe构造函数里的exceptionFactory属性,但还是搞不定,错误只会打印在控制台。
控制台错误信息:
[Nest] 11820 - 01/07/2023, 11:12:25 PM ERROR [WsExceptionsHandler] Bad Request Exception BadRequestException: Bad Request Exception
相关代码:
@SubscribeMessage(Stream.Transactions) @UseGuards(JwtAuthGuard) @UsePipes(new ValidationPipe()) handleTransactions( clien: any, @MessageBody() data: TransactionObject, ) { let req = this.streamService.transaction(data) return { event: Stream.Transactions, data: req } }
解决方案
你当前使用的是WebSocket场景,Nest默认的ValidationPipe抛出的BadRequestException是HTTP专属异常,WsExceptionsHandler不会自动将这类异常推送给客户端,需要调整校验配置:
自定义ValidationPipe的异常工厂
让ValidationPipe抛出WebSocket兼容的WsException,同时格式化校验错误信息,方便客户端接收:@UsePipes(new ValidationPipe({ exceptionFactory: (validationErrors) => { const formattedErrors = validationErrors.map(error => ({ field: error.property, reasons: Object.values(error.constraints || {}) })); return new WsException({ code: 'VALIDATION_FAILED', message: '提交数据不符合要求', details: formattedErrors }); }, whitelist: true, // 自动过滤DTO中未定义的字段 transform: true // 自动将请求数据转换为DTO类型 }))客户端接收错误
抛出WsException后,Nest会自动向客户端发送exception事件,客户端需要监听该事件来获取错误信息,示例格式:{ "event": "exception", "data": { "code": "VALIDATION_FAILED", "message": "提交数据不符合要求", "details": [...] } }全局配置WebSocket校验(可选)
若多个WebSocket控制器需要校验,可在网关中全局配置ValidationPipe,避免重复代码:import { WsAdapter } from '@nestjs/platform-ws'; import { INestApplication } from '@nestjs/common'; @WebSocketGateway() export class TransactionsGateway { constructor(private app: INestApplication) { app.useWebSocketAdapter(new WsAdapter(app)); app.useGlobalPipes(new ValidationPipe({ exceptionFactory: (errors) => new WsException({ errors: errors.map(err => `${err.property}: ${Object.values(err.constraints).join(', ')}`) }) })); } }
内容的提问来源于stack exchange,提问作者Luka Fridonich Donadze
相关产品推荐
相关产品推荐

