I have a NestJs dto that looks like this
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;
}
I am using an exception filter that returns errors with clear details on what validation failed and for which field.
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',
});
},
}),
);
which returns an error something like this
{"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"}
But for the failed validation such as @NotIn, i would want the error to be more specific in terms of what are the reserved keywords, and want them returned in the error as a separate key like:
{"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"}
But this block from the exception Filter doesnt return the constraints values with the decorator metadata.
message: validationErrors.reduce((acc, error) => {
acc[error.property] = Object.keys(error.constraints).map(
(failed) => ({
failedValidation: failed,
message: error.constraints[failed],
}),
);
return acc;
}, {}),
error: 'validation',
});