class-validator icon indicating copy to clipboard operation
class-validator copied to clipboard

fix: @IsUUID(version?: UUIDVersion) not working

Open ouwais-chaoui opened this issue 1 year ago • 4 comments

Description

I want to validate my DTO by using the @IsUUID(version?: UUIDVersion) anotation. The problem is when I add it to my DTO, I don't get an error 400 saying that the string is not a UUID.

Minimal code-snippet showcasing the problem

export class ProductDto extends PickType(Product, [
  'id',
]) {
  @ApiProperty({
    example: '64f52fdb-7621-454f-a35e-524ee2ab3466',
    type: 'string',
    format: 'uuid',
  })
  @IsUUID(4)
  id: string;
}

@Controller('products')
export class ProductController {

  @ApiParam({
    name: 'id',
    type: String,
    required: true,
  })
  @ApiOkResponse({
    description: 'Ok',
    schema: {
      $ref: getSchemaPath(ProductDto),
    },
  })
  @Get('/:id')
  async findById(@Param('id') id: string): Promise<ProductDto> {
    XXXXXXXX
  }
}

Expected behavior

Error 400

{ "statusCode": 400, "error": "Bad Request", "message": [ "expecting UUID", ] }

Actual behavior

Error 500

TypeORM crashes because it expects an UUID ...

ouwais-chaoui avatar May 08 '23 17:05 ouwais-chaoui

I am also facing the same issue,when applied using the version 0.14.0 of class-validator

Areebsofyrus avatar May 10 '23 08:05 Areebsofyrus

You doesn't validate the request. You only use the DTO for the response.

Try to use following code:

export class ProductController {

  @ApiParam({
    name: 'id',
    type: String,
    required: true,
  })
  @ApiOkResponse({
    description: 'Ok',
    schema: {
      $ref: getSchemaPath(ProductDto),
    },
  })
  @Get('/:id')
  async findById(@Param() params: ProductDto): Promise<ProductDto> {
    XXXXXXXX and call id with params.id
  }
}

christian-forgacs avatar May 16 '23 11:05 christian-forgacs

Tested with this code, don't find any problem:

/* eslint-disable no-process-exit */
import { plainToInstance } from 'class-transformer';
import { v4 as uuidV4 } from 'uuid';
import { IsUUID, validate } from 'class-validator';

class ProductDto {
  @IsUUID(4)
  id: string;
}

(async () => {
  const idInstance = plainToInstance(ProductDto, { id: uuidV4() });
  console.log(idInstance); // ProductDto { id: '3dfa81bc-aacf-449a-bb0b-15b49c4724e7' }
  console.log(await validate(idInstance)); // []

  const idInstance2 = plainToInstance(ProductDto, { id: '123' });
  console.log(idInstance2); // ProductDto { id: '123' }
  console.log(await validate(idInstance2));
  // [
  //   ValidationError {
  //     target: ProductDto { id: '123' },
  //     value: '123',
  //     property: 'id',
  //     children: [],
  //     constraints: { isUuid: 'id must be a UUID' }
  //   }
  // ]
})()
  .then(() => {
    process.exit(0);
  })
  .catch((error) => {
    console.log(error);
    process.exit(1);
  });

Your showcase is not complete, also mixed with nestjs content. Please make sure it is a class-validator problem by removing all unrelated context first

kpkonghk01 avatar Jun 21 '23 04:06 kpkonghk01