user3788133
user3788133

Reputation: 303

How to change the format of NestJS controller/class-validator error messages showing which field each message belongs to?

The NestJS controller, along with the class-validator, currently returns an error message like this:

{
  statusCode: 422,
  message: [ 'Name is required', 'Email is required' ],
  error: 'Unprocessable Entity'
}

But I would like to bind each message to its related property like this:

{
  statusCode: 422,
  message: { name: 'Name is required', email: 'Email is required' },
  error: 'Unprocessable Entity'
}

My DTO:

import { IsNotEmpty } from 'class-validator';

export class CreateUserRequestDTO {
  @IsNotEmpty({ message: 'Name is required' })
  name: string;

  @IsNotEmpty({ message: 'Email is required' })
  email: string;
}

How could I change the NestJS controller/class-validator errors to return messages like this?

Upvotes: 2

Views: 1870

Answers (2)

123
123

Reputation: 1

It`s works for single object, if you need universal code, there is other variant

const errorMessages = {};
    function handleErrors(errors: any[], prefix = '') {
      errors.forEach((err) => {
        if (err.constraints) {
          Object.values(err.constraints).forEach((message: string) => {
            const fieldName = prefix + err.property;
            errorMessages[fieldName] = message;
          });
        }

        if (err.children && err.children.length > 0) {
          handleErrors(err.children, `${prefix + err.property}.`);
        }
      });
    }

    handleErrors(errors);

result in errorMessages

Upvotes: 0

Bogdan Onischenko
Bogdan Onischenko

Reputation: 655

The response for validation errors can be modified by passing exceptionFactory to the ValidationPipe options.

https://docs.nestjs.com/techniques/validation

See example implementation:

app.useGlobalPipes(
  new ValidationPipe({
    exceptionFactory: (errors) => {
      return new UnprocessableEntityException({
        statusCode: 422,
        error: 'Unprocessable Entity',
        message: errors.reduce(
          (acc, e) => ({
            ...acc,
            [e.property]: Object.values(e.constraints),
          }),
          {},
        ),
      });
    },
  }),
);

Upvotes: 7

Related Questions