Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional Enums with SWC throw validation errors (400) #14430

Open
4 of 15 tasks
lucas-gregoire opened this issue Jan 15, 2025 · 1 comment
Open
4 of 15 tasks

Optional Enums with SWC throw validation errors (400) #14430

lucas-gregoire opened this issue Jan 15, 2025 · 1 comment
Labels
needs triage This issue has not been looked into

Comments

@lucas-gregoire
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

When using SWC as builder, optional enums in NestJS fail validation and throw a 400 error.

If I define a controller like this:

@Get()
example(
  @Query('test', new ParseEnumPipe(MyEnum, { optional: true })) test?: MyEnum,
) {
  return `result:${test}`;
}

When querying without the test query param I get this:

{
  "message": "Validation failed (enum string is expected)",
  "error": "Bad Request",
  "statusCode": 400
}

This issue does not occur when using TypeScript as builder.
It is related to a previous problem reported in #12680, which was partially fixed in #14181. While the fix resolved the 500 error, it now throws a 400 error when using SWC.

Minimum reproduction code

https://codesandbox.io/p/devbox/goofy-darwin-lmzv37?file=%2Fsrc%2Fapp.controller.ts

Steps to reproduce

  • Run the project using SWC as the builder (npm run start:swc).
  • Open a browser on port 300 or send a GET request without the test query parameter or with an empty value.
  • Observe the 400 error response.
  • Switch to TypeScript as the builder (npm run start)
  • Send the same request, and note that no error is thrown (200) => result:undefined is returned as expected.

Expected behavior

Optional enums should not throw a validation error when the value is undefined, null or not provided in the request payload, regardless of whether SWC or TypeScript is used as the builder.

Therefore in the exemple it must pass undefined in the test parameter

Package

  • I don't know. Or some 3rd-party package
  • @nestjs/common
  • @nestjs/core
  • @nestjs/microservices
  • @nestjs/platform-express
  • @nestjs/platform-fastify
  • @nestjs/platform-socket.io
  • @nestjs/platform-ws
  • @nestjs/testing
  • @nestjs/websockets
  • Other (see below)

Other package

No response

NestJS version

10.4.15

Packages versions

"dependencies": {
    "@nestjs/common": "^10.4.15",
    "@nestjs/core": "^10.4.15",
    "@nestjs/platform-express": "^10.4.15",
    "@swc/jest": "^0.2.37",
    "class-transformer": "^0.5.1",
    "class-validator": "^0.14.1",
    "reflect-metadata": "^0.2.2",
    "rxjs": "^7.8.1"
  },

Node.js version

20.12.0

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

@lucas-gregoire
Copy link
Author

lucas-gregoire commented Jan 15, 2025

I found a workaround for this issue in an SWC environment which seems to work well on my project.
The goal is to extends the ValidationPipe in order to force the handling of Enums as String.

import { ArgumentMetadata, ValidationPipe as NestValidationPipe } from '@nestjs/common';
import { isObject } from '@nestjs/common/utils/shared.utils';

export class ValidationPipe extends NestValidationPipe {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  override transform(value: any, metadata: ArgumentMetadata): any {
    // Change metatype of enums to String to avoid SWC unwanted behavior: https://github.com/nestjs/nest/issues/14430
    if (isObject(metadata.metatype) && typeof metadata.metatype !== 'function') {
      return super.transform(value, { ...metadata, metatype: String });
    }
    return super.transform(value, metadata);
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs triage This issue has not been looked into
Projects
None yet
Development

No branches or pull requests

1 participant