当我将
@ValidateNested()
与 class-validator
一起使用时,嵌套对象的输出如下所示:
// Object Schema:
export class CreateServerSettingsDTO {
@IsNotEmpty({ message: 'Username is required' })
username: string;
@IsNotEmpty({ message: 'Password is required' })
password: string;
}
export class CreateServerDTO {
@IsNotEmpty({ message: 'Server name is required' })
serverName: string;
description?: string;
@ValidateNested()
@Type(() => CreateServerSettingsDTO)
@IsObject({ message: 'Settings must be an object' })
@IsNotEmpty({ message: 'Settings are required' })
settings: CreateServerSettingsDTO;
}
// Validation response:
{
"statusCode": 400,
"message": [
"settings.Username is required",
"settings.Password is required"
],
"error": "Bad Request"
}
相反,我希望
settings
对象的消息看起来像:
{
"statusCode": 400,
"message": [
"Username is required",
"Password is required"
],
"error": "Bad Request"
}
我无法找到从嵌套属性消息中删除
settings.
前缀的方法。我该怎么做?
我找到的最好的方法
formatErrors.ts
import { ValidationPipe, BadRequestException } from '@nestjs/common';
import { ValidationError } from 'class-validator';
type IErrorMessage = Record<string, any>;
function formatErrorsHelper(errors: ValidationError[]): IErrorMessage[] {
return errors.map((item): IErrorMessage => {
const { property, constraints, children } = item;
const result: IErrorMessage = {};
if (constraints) {
result[property] = Object.values(constraints);
}
if (Array.isArray(children) && children.length > 0) {
result[property] = formatErrorsHelper(children);
}
return result;
});
}
export const formatErrorPipe = new ValidationPipe({
exceptionFactory: (errors: ValidationError[]) => {
return new BadRequestException(formatErrorsHelper(errors));
},
});
main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app/app.module';
import { formatErrorPipe } from './helpers/formatErrors';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(formatErrorPipe);
await app.listen(3000);
}
bootstrap();
**format-pipe-errors.helper.ts**
import { ValidationPipe, BadRequestException } from '@nestjs/common';
import { ValidationError } from 'class-validator';
function formatPipeErrorsHelper(errors: ValidationError[]): string[] {
const errorMessages: string[] = [];
function extractMessages(error: ValidationError) {
if (error.constraints) {
errorMessages.push(...Object.values(error.constraints));
}
if (error.children && error.children.length > 0) {
error.children.forEach(extractMessages);
}
}
errors.forEach(extractMessages);
return errorMessages;
}
export const formatErrorPipe = new ValidationPipe({
whitelist: true,
forbidNonWhitelisted: true,
exceptionFactory: (errors: ValidationError[]) => {
throw new BadRequestException(formatPipeErrorsHelper(errors));
},
});
main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app/app.module';
import { formatErrorPipe } from './helpers/formatErrors';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(formatPipeErrorsHelper);
await app.listen(3000);
}
bootstrap();