如何在NestJS ValidationPipe的exceptionFactory中获取@Min约束值
问题
我在创建NestJS应用时,想自定义class-validator的提示消息,写了一个根据消息键返回自定义消息的函数。但现在遇到个问题:在exceptionFactory的错误对象里,拿不到DTO中@Min装饰器设置的最小值(示例里是1),只能拿到自定义消息键'validation.min'。我不想用context(避免重复传值和装饰器冗余),该怎么获取@Min的设置值?
DTO代码
class GetUsersDto { @ApiProperty({ required: false }) @IsOptional() @Min(1, { message: 'validation.min' }) @IsInt() @Transform((param) => parseInt(param.value, 10)) page?: number; }
全局ValidationPipe配置
app.useGlobalPipes( new ValidationPipe({ stopAtFirstError: true, whitelist: true, forbidNonWhitelisted: true, transform: true, exceptionFactory: (errors) => { console.log(errors); const result = errors .map((error) => { const key = Object.values(error.constraints)[0]; const message = getMessage(key, error); return message ? message : getMessage('validation.400'); }) .join(''); return new BadRequestException(result); }, }), );
exceptionFactory中打印的错误信息
[ ValidationError { target: GetUsersDto { page: -1 }, value: -1, property: 'page', children: [], constraints: { min: 'validation.min' } } ]
解决方案
你可以借助class-validator内置的getMetadataStorage()方法,直接从元数据中读取@Min装饰器的设置值,无需依赖context传值。具体实现步骤如下:
- 导入class-validator的元数据存储工具:
import { getMetadataStorage } from 'class-validator';
- 编写工具函数,通过目标类和属性名查找对应的Min约束参数:
const getMinConstraintValue = (targetClass: any, propertyName: string): number | undefined => { const metadataStorage = getMetadataStorage(); // 筛选出当前属性对应的Min约束元数据 const minConstraint = metadataStorage.constraints.find( item => item.target === targetClass && item.propertyName === propertyName && item.type === 'min' ); // 返回设置的最小值 return minConstraint?.constraints[0]; };
- 在exceptionFactory中调用该函数,获取最小值并传入消息生成逻辑:
exceptionFactory: (errors) => { const result = errors .map((error) => { const key = Object.values(error.constraints)[0]; // 获取@Min设置的最小值 const minValue = getMinConstraintValue(error.target.constructor, error.property); // 将最小值传入getMessage生成自定义提示 const message = getMessage(key, error, minValue); return message ? message : getMessage('validation.400'); }) .join(''); return new BadRequestException(result); },
这样就能在不增加装饰器冗余的前提下,拿到@Min设置的最小值,用于生成自定义提示消息。
内容的提问来源于stack exchange,提问作者Ako
相关产品推荐
相关产品推荐

