Skip to content

Commit 8e8d515

Browse files
authored
Export ZodSerializationException so consumers can log serialization errors (#115)
1 parent f6911cf commit 8e8d515

File tree

5 files changed

+43
-4
lines changed

5 files changed

+43
-4
lines changed

README.md

+12
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,18 @@ export class UserController {
348348

349349
In the above example, despite the `userService.findOne` method returns `password`, the `password` property will be stripped out thanks to the `@ZodSerializerDto` decorator.
350350

351+
### Logging serialization errors using `ZodSerializationException`
352+
353+
You can catch serialization errors using `ZodSerializationException` and log them using your preferred logger.
354+
355+
```ts
356+
if (exception instanceof ZodSerializationException) {
357+
const zodError = exception.getZodError();
358+
this.logger.error(`ZodSerializationException: ${zodError.message}`);
359+
}
360+
```
361+
See the example app [here](/packages/example/src/http-exception.filter.ts) for more information.
362+
351363
## Extended Zod
352364

353365
> [!CAUTION]

packages/example/src/app.module.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { Module } from '@nestjs/common';
2-
import { ZodValidationPipe } from 'nestjs-zod'
3-
import { APP_PIPE } from '@nestjs/core'
2+
import { ZodSerializerInterceptor, ZodValidationPipe } from 'nestjs-zod'
3+
import { APP_FILTER, APP_INTERCEPTOR, APP_PIPE } from '@nestjs/core'
44
import { AppController } from './app.controller';
55
import { AppService } from './app.service';
66
import { PostsModule } from './posts/posts.module';
7+
import { HttpExceptionFilter } from './http-exception.filter';
78

89

910
@Module({
@@ -15,6 +16,14 @@ import { PostsModule } from './posts/posts.module';
1516
provide: APP_PIPE,
1617
useClass: ZodValidationPipe,
1718
},
19+
{
20+
provide: APP_INTERCEPTOR,
21+
useClass: ZodSerializerInterceptor,
22+
},
23+
{
24+
provide: APP_FILTER,
25+
useClass: HttpExceptionFilter,
26+
},
1827
]
1928
})
2029
export class AppModule {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Logger, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
2+
import { BaseExceptionFilter } from '@nestjs/core';
3+
import { ZodSerializationException } from 'nestjs-zod';
4+
5+
@Catch(HttpException)
6+
export class HttpExceptionFilter extends BaseExceptionFilter {
7+
private readonly logger = new Logger(HttpExceptionFilter.name);
8+
9+
catch(exception: HttpException, host: ArgumentsHost) {
10+
if (exception instanceof ZodSerializationException) {
11+
const zodError = exception.getZodError();
12+
this.logger.error(`ZodSerializationException: ${zodError.message}`);
13+
}
14+
15+
super.catch(exception, host);
16+
}
17+
}

packages/example/src/posts/posts.controller.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Body, Controller, Get, Param, Post } from '@nestjs/common';
22
import { ApiOkResponse } from '@nestjs/swagger';
3-
import { createZodDto } from 'nestjs-zod'
3+
import { createZodDto, ZodSerializerDto } from 'nestjs-zod'
44
import { z } from 'zod'
55

66
class PostDto extends createZodDto(z.object({
@@ -23,6 +23,7 @@ export class PostsController {
2323
}
2424

2525
@Get(':id')
26+
@ZodSerializerDto(PostDto)
2627
@ApiOkResponse({ type: PostDto, description: 'Get a post by ID' })
2728
getById(@Param('id') id: string) {
2829
return {

packages/nestjs-zod/src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export type { ZodDto } from './dto'
22
export { createZodDto } from './dto'
3-
export { ZodValidationException } from './exception'
3+
export { ZodValidationException, ZodSerializationException } from './exception'
44
export { createZodGuard, UseZodGuard, ZodGuard } from './guard'
55
export { patchNestJsSwagger, zodToOpenAPI } from './openapi'
66
export { createZodValidationPipe, ZodValidationPipe } from './pipe'

0 commit comments

Comments
 (0)