我有一个 NestJs dto,看起来像这样
import { IsEmail, IsNotEmpty, IsNotIn } from 'class-validator';
import { AppService } from './app.service';
const restrictedNames = ['Name Inc', 'Acme Inc'];
class DTO {
@IsNotEmpty()
name: string;
@IsEmail()
email: string;
@IsNotEmpty()
@IsNotIn(restrictedNames)
orgName: string;
}
我正在使用一个异常过滤器,它返回错误,并提供有关验证失败的内容和哪个字段的清晰详细信息。
app.useGlobalPipes(
new ValidationPipe({
exceptionFactory: (validationErrors: ValidationError[] = []) => {
console.log(validationErrors);
return new BadRequestException({
statusCode: HttpStatus.BAD_REQUEST,
message: validationErrors.reduce((acc, error) => {
acc[error.property] = Object.keys(error.constraints).map(
(failed) => ({
failedValidation: failed,
message: error.constraints[failed],
}),
);
return acc;
}, {}),
error: 'validation',
});
},
}),
);
返回类似这样的错误
{"statusCode":400,"message":{"email":[{"failedValidation":"isEmail","message":"email must be an email"}],"orgName":[{"failedValidation":"isNotIn","message":"orgName should not be one of the following values: Name Inc, Acme Inc"}]},"error":"validation"}
但是对于失败的验证(例如@NotIn),我希望错误在保留关键字方面更加具体,并希望它们作为单独的键在错误中返回,例如:
{"statusCode":400,"message":{"email":[{"failedValidation":"isEmail","message":"email must be an email"}],"orgName":[{"failedValidation":"isNotIn","message":"orgName should not be one of the following values: Name Inc, Acme Inc", "data":{"reservedKeywords":["Name Inc","Acme Inc"]}}]},"error":"validation"}
但是异常 Filter 中的此块不会返回带有装饰器元数据的约束值。
message: validationErrors.reduce((acc, error) => {
acc[error.property] = Object.keys(error.constraints).map(
(failed) => ({
failedValidation: failed,
message: error.constraints[failed],
}),
);
return acc;
}, {}),
error: 'validation',
});
据我所知,不存在自动返回元数据或任何其他内容的概念。由于您将列入黑名单的值存储在变量中。您可以将其提供为
context
,它映射到特定的错误类型。
const restrictedNames = ['Name Inc', 'Acme Inc'] as const;
class DTO {
@IsNotEmpty()
name: string;
@IsEmail()
email: string;
@IsNotEmpty()
@IsNotIn(restrictedNames, { context: { reservedKeywords: restrictedNames } }) // here
orgName: string;
// You may ignore the contructor
constructor(name: string, email: string, orgName: string) {
this.name = name;
this.email = email;
this.orgName = orgName;
}
}
现在您需要做的就是使用
error.contexts
有条件地将值包含在转换函数中
const transformedMessage = errors.reduce((acc, error) => {
acc[error.property] = Object.keys(error.constraints).map((failed) => ({
failedValidation: failed,
message: error.constraints[failed],
data: error.contexts && error.contexts[failed],
}));
return acc;
}, {});
如您所愿,这是输出。
{
"email": [
{
"failedValidation": "isEmail",
"message": "email must be an email"
}
],
"orgName": [
{
"failedValidation": "isNotIn",
"message": "orgName should not be one of the following values: Name Inc, Acme Inc",
"data": {
"reservedKeywords": [
"Name Inc",
"Acme Inc"
]
}
}
]
}
PS:感谢提供转换功能。我可耻地偷了它。