I want class validator to stop validation as soon as the first error is found.
I know there is a stopAtFirstError
option, but that prevents further validation on property level only. I want to stop it globally:
@IsString() // Let's say this received invalid value
someStr: string
@IsInt() // I want this to be NOT executed
someNuber: number
Is this possible?
Since there is no official support for this, I implemented a hacky way to make it work. Although it doesn't stop the validation, only returns the message from initial one & ignores the rest.
// validation-error.exception.ts
import { HttpException, HttpStatus } from "@nestjs/common";
export class ValidationErrorException extends HttpException {
data: any;
constructor(data: any) {
super('ValidationError', HttpStatus.BAD_REQUEST);
this.data = data
}
getData(){
return this.data;
}
}
// main.ts
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
forbidNonWhitelisted: true,
stopAtFirstError: true,
exceptionFactory: (errors: ValidationError[]) => {
return new ValidationErrorException(errors);
},
}),
);
// validation-error.filter.ts
import { ExceptionFilter, Catch, ArgumentsHost } from '@nestjs/common';
import { Response } from 'express';
import { ValidationErrorException } from './validation-error.exception';
@Catch(ValidationErrorException)
export class ValidationErrorFilter implements ExceptionFilter {
catch(exception: ValidationErrorException, host: ArgumentsHost) {
const response = host.switchToHttp().getResponse<Response>();
const status = exception.getStatus();
let constraints = exception.getData()[0].constraints
response
.status(status)
.json({
statusCode: status,
message: constraints[Object.keys(constraints)[0]],
error: exception.message
});
}
}
// app.module.ts
providers: [
{
provide: APP_FILTER,
useClass: ValidationErrorFilter,
},
],