Closed recallwei closed 2 days ago
Maybe the expression above is not good. The query string type
here is required. But when it is not passed, should return a friendly error message.
Would you like to create a PR for this issue?
If not, please provide a minimum reproduction repository (Git repository/StackBlitz/CodeSandbox project).
create a custom validation to ensure the parameter exists before trying to parse it. Here's an example:
`@Post('login')
async login(
@Query('type') type: string,
@Body() loginDto: LoginDto,
@I18n() i18n: I18nContext
// At this point, you know that 'type' exists and is a valid LoginType enum value. // You can now safely use it. } `
This way, you avoid the ParseEnumPipe from directly trying to parse an undefined value.
@recallwei please double-check if this isn't due to the line
const i18n = I18nContext.current<I18nTranslations>()!
@recallwei please double-check if this isn't due to the line
const i18n = I18nContext.current<I18nTranslations>()!
Sorry for wasting everyone's time. I created a minimal repository for reproduction at codesandbox, but everything is ok. It confused me a lot. The error occurs when the pipeline executes transform.
My origin repo at https://github.com/bit-ocean-studio/dolphin-admin-nest
I tried to make another reproduction at https://codesandbox.io/p/github/bit-ocean-studio/dolphin-admin-nest/main?file=%2Fsrc%2Fmodules%2Fauth%2Fauth.controller.ts%3A32%2C48&workspaceId=9227e773-346e-4830-aeb4-a342dcced73b This is a copy from my repo, I deleted most of the files that are not related to this error to make this repro clean(like database and other modules).
API endpoint is /auth/login
I ran into a similar problem today. It happens only when I use swc. If I disable it, everything works correctly.
Method example:
export enum City {
KRD = 'krd',
SOCHI = 'sochi',
}
...
@Get(':query')
@ApiOperation({
tags: ['search'],
summary: 'Search for services/doctors/price by name',
})
@ApiParam({
name: 'query',
description: 'Query text',
})
@ApiQuery({
name: 'city',
required: false,
enum: City,
description:
'City identifier. May be omitted, default value is `krd`.',
})
@ApiOkResponse({
description: 'Returns an object with a successful or empty search result',
})
getSearch(
@Param('query') query: string,
@Query('city') city: City,
) {
return this.searchService.search(query, city);
}
I also have ValidationPipe globally installed
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
transform: true,
}),
);
If I set the variable type as string then everything works, if I set enum then it doesn't work with swc. When setting ParseEnumPipe the situation is similar.
@Query('city', new ParseEnumPipe(City, { optional: true })) city: City,
@JoCat please share a minimum reproduction repository.
I remember that I also used swc.
@JoCat please share a minimum reproduction repository.
I am facing the exact same issue and disabling SWC indeed helps !
Should we open an issue on swc repo, so a fix can be implemented ?
@JoCat not sure if I follow. I just tested your repro and everything went fine here. Both tsc and swc are behaving the same
@Tchekda please share a minimum reproduction repository here if you believe that this is related with Nestjs
@micalevisk The repo was already shared above. To be honest, I don't really know whose fault it is (nestjs, swc, class-transformer) but what is clear:
If you use ParseEnumPipe
from NestJs with an optional query param, you get an error when the complier is swc
but not when it's the default one (webpack ?).
Here was the bug report I made on the discord server:
I have an endpoint with an optional query param called mapType
which can be of type MapType
(a TS enum with 2 values)
My controller function looks like this:
enum MapType {
regionMap = 'regionMap',
regionMapPolygon = 'regionMapPolygon',
}
all(
@Query('mapType', new ParseEnumPipe(MapType)) mapType: MapType,
): Promise<MapResponseDto> {
When there is a mapType
param in my request, it all works as expected. But when I don't put it (no key no value) I get a class-transformer error:
The error comes from MetadataStorage.getAncestors
with Cannot read properties of undefined (reading 'constructor')
because it's trying to access target.prototype.constructor
After some debugging, here is what I found:
target
passed to that variable is a plain object representing my enum, which explains why it doesn't have any prorotype: { regionMap: 'regionMap', regionMapPolygon: 'regionMapPolygon' }
ParseEnumPipe
but the transform
function is never called when the error occursMapType
in my case) and then passed to the pipe.target
in class-transformer is [Function: String]
:
all(
@Query('mapType', new ParseEnumPipe(MapType)) mapType: string,
): Promise<MapResponseDto> {
[Function: Object]
as target
:
all(
@Query('mapType', new ParseEnumPipe(MapType)) mapType: keyof typeof MapType,
): Promise<MapResponseDto> {
Let's track this here https://github.com/nestjs/nest/pull/14181
Is there an existing issue for this?
Current behavior
I want to parse a query property which is an enum type using ParseEnumPipe.
But if query
type
is undefined, nest will throw an error below:To avoid this error, I must change
type: LoginType
totype: string
. Is this expected behaviour?Minimum reproduction code
The above code
Steps to reproduce
Parse an enum query string using ParseEnumPipe.
Expected behavior
type: LoginType
should work, expect this query string to be parsed as an enum type.Package
Other package
No response
NestJS version
10.2.7
Packages versions
Node.js version
20 lts
In which operating systems have you tested?
Other
No response