diff --git a/src/application/dtos/point.dto.ts b/src/application/dtos/point.dto.ts index d17c506..8b96b1d 100644 --- a/src/application/dtos/point.dto.ts +++ b/src/application/dtos/point.dto.ts @@ -6,7 +6,7 @@ export class PointDto { default: 1000, }) @IsInt() - @IsPositive() + @IsPositive({ message: '금액은 0보다 커야 합니다.' }) amount: number; @ApiProperty({ diff --git a/src/application/filters/global-exception.filter.ts b/src/application/filters/global-exception.filter.ts new file mode 100644 index 0000000..801f7d1 --- /dev/null +++ b/src/application/filters/global-exception.filter.ts @@ -0,0 +1,40 @@ +import { + Catch, + ArgumentsHost, + HttpStatus, + HttpException, + Logger, +} from '@nestjs/common'; +import { Response } from 'express'; + +@Catch() +export class HttpExceptionsFilter { + private readonly logger: Logger = new Logger('ExceptionsFilter'); + + public catch(exception: unknown, host: ArgumentsHost): void { + const ctx = host.switchToHttp(); + const res = ctx.getResponse(); + + let status: number = HttpStatus.INTERNAL_SERVER_ERROR; + let response: string | object = { + statusCode: status, + message: 'Internal server error', + }; + if (exception instanceof HttpException) { + status = exception.getStatus(); + response = exception.getResponse(); + } + + if (status >= HttpStatus.INTERNAL_SERVER_ERROR) { + this.logger.error( + `Http status: ${status} Error Response: ${JSON.stringify(response)}`, + ); + } else { + this.logger.warn( + `Http status: ${status} Error Response: ${JSON.stringify(response)}`, + ); + } + + res.status(status).json(response); + } +} diff --git a/src/application/modules/app.module.ts b/src/application/modules/app.module.ts index bd75df4..c8bb0aa 100644 --- a/src/application/modules/app.module.ts +++ b/src/application/modules/app.module.ts @@ -4,6 +4,7 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import dataSource from '@infrastructure/typeorm/data-source'; import { AppController } from '@application/controllers'; import { AppService } from '@domain/services'; +import { HttpExceptionsFilter } from '../filters/global-exception.filter'; const modulesList = Object.keys(modules).map( (moduleIndex) => modules[moduleIndex as keyof typeof modules], @@ -20,6 +21,10 @@ const modulesList = Object.keys(modules).map( provide: 'DataSource', useValue: dataSource, }, + { + provide: 'APP_FILTER', + useClass: HttpExceptionsFilter, + }, ], controllers: [AppController], }) diff --git a/src/main.ts b/src/main.ts index 5fdcdb6..b7a633a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,10 +1,18 @@ import { NestFactory } from '@nestjs/core'; import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; import { AppModule } from '@application/modules/app.module'; +import { ValidationPipe } from '@nestjs/common'; async function bootstrap() { const app = await NestFactory.create(AppModule); + app.useGlobalPipes( + new ValidationPipe({ + transform: true, + transformOptions: { enableImplicitConversion: true }, + }), + ); + const swaggerConfig = new DocumentBuilder() .setTitle('E-commerce API') .setDescription('E-commerce API 문서')