Alexandr
Alexandr

Reputation: 21

Several errors instead one

I am using https://www.npmjs.com/package/nestjs-joi and https://www.npmjs.com/package/joi for validating my NestJS app's request.

I have a schema for creating user

@JoiSchemaOptions({
  allowUnknown: false,
})
export class UserDto {
  @JoiSchema(Joi.string().required())
  @JoiSchema([CREATE], Joi.string().required())
  @JoiSchema([UPDATE], Joi.string().optional())
  name: string;

  @JoiSchema(Joi.string().required())
  @JoiSchema([CREATE], Joi.string().required())
  @JoiSchema([UPDATE], Joi.string().optional())
  surname: string;

  @JoiSchema([CREATE], Joi.string().email({ minDomainSegments: 2 }).required())
  email: string;

  @JoiSchema([CREATE], Joi.string().min(6).required())
  password: string;
}

User Controller: I use it like says netsjs-joi, give UserDto as an argument in the controller, I think maybe I need some error handler for this and prepare my error like how I want, but is there something out of the box in Joi

import {
  Controller,
  Get,
  Param,
  BadRequestException,
  Post,
  Body,
} from '@nestjs/common';

import { UserService } from './user.service';
import { UserDto } from './dto/user.dto';

@Controller('user')
export class UserController {
  constructor(private userService: UserService) {}

  @Post()
  create(@Body() createData: UserDto): string {
    console.log(JSON.stringify(createData, null, 2));
    return 'something';
  }
}

And when I send a request with this body

{
    "name": "name",
    "surname": "",
    "email": "error",
    "password": "error"
}

I get error

{
    "statusCode": 400,
    "message": "Request validation of body failed, because: \"surname\" is not allowed to be empty, \"email\" must be a valid email, \"password\" length must be at least 6 characters long",
    "error": "Bad Request"
}

But I want to get for example something like this

[ {
"statusCode": 400,
    "message": "Request validation of body failed, because: \"surname\" is not allowed to be empty,",
    "error": "Bad Request",
"surname": "Surname is not allow to be empty",
},
{
    "statusCode": 400,
    "message": "Request validation of body failed, because: \"email\" must be a valid email",
    "error": "Bad Request",
"email": "Email must be a valid email"
},
...
]

Any ideas? Thanks!))

Upvotes: 2

Views: 148

Answers (2)

Alexandr
Alexandr

Reputation: 21

I deleted nestjs-joi and created usual Joi schema

    import * as Joi from 'joi';
    
    export default Joi.object({
      name: Joi.string().required(),
      surname: Joi.string().required(),
      email: Joi.string().email({ minDomainSegments: 2 }).required(),
      password: Joi.string().min(6).required(),
    });

After this created JoiValidationPipe

import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';
import { ObjectSchema } from 'joi';

@Injectable()
export class JoiValidationPipe implements PipeTransform {
  constructor(private schema: ObjectSchema) {}

  transform(value: any, metadata: ArgumentMetadata) {
    const { error } = this.schema.validate(value, {
      abortEarly: false,
      allowUnknown: false,
    });
    if (error) {
      throw error;
    }
    return value;
  }
}

And use it like this in the controller

@Controller('user')
export class UserController {
  constructor(private userService: UserService) {}

  @Post()
  @UsePipes(new JoiValidationPipe(UserCreateSchema))
  create(@Body() createData: CreateUser): string {
    return 'createData';
  }
}

Upvotes: 0

Nithin K Joy
Nithin K Joy

Reputation: 963

Try this

@JoiSchemaOptions({
  allowUnknown: false,
  abortEarly:false   //added this line here
})
export class UserDto {
  @JoiSchema(Joi.string().required())
  @JoiSchema([CREATE], Joi.string().required())
  @JoiSchema([UPDATE], Joi.string().optional())
  name: string;

  @JoiSchema(Joi.string().required())
  @JoiSchema([CREATE], Joi.string().required())
  @JoiSchema([UPDATE], Joi.string().optional())
  surname: string;

  @JoiSchema([CREATE], Joi.string().email({ minDomainSegments: 2 }).required())
  email: string;

  @JoiSchema([CREATE], Joi.string().min(6).required())
  password: string;
}

Upvotes: 1

Related Questions