NestJS自定义ValidationPipe抛异常时全局Exception Filter未被调用问题
问题根因
你的自定义校验管道SchemaValidationPipe的transform方法没有返回异步校验的Promise实例,NestJS无法感知管道内的异步异常,导致异常无法进入全局异常处理链路。
修复方案
你可以选择以下任意一种方式修改管道代码:
方式1:返回Promise链
@Injectable() export class SchemaValidationPipe implements PipeTransform<any> { constructor(private schema: any) {} transform(value: any, metadata: ArgumentMetadata) { const schemaValidator = new JsonValidator(this.schema); // 新增return,将整个异步链路返回给Nest框架 return schemaValidator .validate(value) .then((data) => { if (data) { const { isValid, message } = data; if(!isValid) throw new BadRequestException( { status : '500', message : 'Validation failed' } ); } return value; }) .catch((err) => { throw new BadRequestException('Validation failed'); }); } }
方式2:使用async/await语法(更易维护)
@Injectable() export class SchemaValidationPipe implements PipeTransform<any> { constructor(private schema: any) {} async transform(value: any, metadata: ArgumentMetadata) { try { const schemaValidator = new JsonValidator(this.schema); const data = await schemaValidator.validate(value); if (data) { const { isValid } = data; if(!isValid) throw new BadRequestException( { status : '500', message : 'Validation failed' } ); } return value; } catch (err) { throw new BadRequestException('Validation failed'); } } }
原理解释
NestJS的管道支持同步返回值和异步Promise两种返回类型,当管道内存在异步逻辑时,必须将异步操作的Promise实例返回给框架,框架才会等待异步操作执行完成,同时捕获异步流程中抛出的异常,递交给全局异常过滤器处理。
你之前的写法没有返回Promise,校验逻辑中抛出的异常属于未捕获的Promise rejection,不会进入Nest的异常处理链路,因此全局过滤器无法捕获。
内容的提问来源于stack exchange,提问作者pravin deore
相关产品推荐
相关产品推荐

