nest
nest copied to clipboard
feat(common): add new flatten options to validation pipe
PR Checklist
Please check if your PR fulfills the following requirements:
- [x] The commit message follows our guidelines: https://github.com/nestjs/nest/blob/master/CONTRIBUTING.md
- [x] Tests for the changes have been added (for bug fixes / features)
- [x] Docs have been added / updated (for bug fixes / features)
PR Type
What kind of change does this PR introduce?
- [ ] Bugfix
- [x] Feature
- [ ] Code style update (formatting, local variables)
- [ ] Refactoring (no functional changes, no api changes)
- [ ] Build related changes
- [ ] CI related changes
- [ ] Other... Please describe:
What is the current behavior?
Currently, when the validation pipe throws an error, the error messages are always flattened into an array of strings. For example:
[
"name must be a string",
"number must be an integer number"
]
This behavior lacks flexibility for scenarios where the original structured error format is needed.
Also for custom exceptionFactory the errors are always returned as an array of ValidationError. For example:
[
{
"target": {},
"property": "name",
"children": [],
"constraints": {
"isString": "name must be a string"
}
},
{
"target": {},
"property": "number",
"children": [],
"constraints": {
"isInt": "number must be an integer number"
}
}
]
What is the new behavior?
This PR introduces a new two options disableFlattenErrorMessages and flatExceptionFactoryMessage in the ValidationPipe to control the formatting of error messages.
disableFlattenErrorMessagesWhen this option is enabled, the errors will retain their original structure instead of being flattened.
For example:
@UsePipes(
new ValidationPipe({
disableFlattenErrorMessages: true
}),
)
The errors will now be returned in the ValidationError structured format:
[
{
"target": {},
"property": "name",
"children": [],
"constraints": {
"isString": "name must be a string"
}
},
{
"target": {},
"property": "number",
"children": [],
"constraints": {
"isInt": "number must be an integer number"
}
}
]
flatExceptionFactoryMessageWhen this option is enabled, andexceptionFactoryis provided, the errors passed to exception factory will be flattened as array of strings
For example:
@UsePipes(new ValidationPipe({ flatExceptionFactoryMessage: true, exceptionFactory: (errors: ValidationError[] | string[]) => new BadRequestException(errors) }))
The errors will now be in format:
[
"name must be a string",
"number must be an integer number"
]
Does this PR introduce a breaking change?
- [x] Yes
- [ ] No
Other information
Motivation
The motivation behind this change stems from a specific use case with WebSocket validation. When using the validation pipe with WebSockets (WebSocket Pipes Documentation), the error messages were not flattened by default. However, when I needed to flatten them, I ended up duplicating the same flattening logic in my exception handler. so I made it configurable.
@UsePipes(new ValidationPipe({ flatExceptionFactoryMessage: true, exceptionFactory: (errors: ValidationError[] | string[]) => new WsException(errors) }))
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
const event = 'events';
return { event, data };
}
Docs PR: https://github.com/nestjs/docs.nestjs.com/pull/3173