- app.useGlobalGuards(new HttpExceptionFilter()) 이렇게 new 로 생성하는 이유는 main.ts 는 NestJS 의 IoC Container 가 완전히 초기화되기 전이기 때문
왜 이렇게 동작할까?
IoC Container의 생명주기
- NestFactory.create() 호출
- AppModule 로드 및 분석
- Metadata 수집 (데코레이터 정보)
- Dependency Injection Container 생성
- Provider 인스턴스화 및 의존성 주입
// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';
import { HttpExceptionFilter } from './common/filters/http-exception/http-exception.filter';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
transform: true,
forbidNonWhitelisted: true,
transformOptions: {
enableImplicitConversion: true,
},
}),
);
app.useGlobalFilters(new HttpExceptionFilter());
await app.listen(process.env.PORT ?? 4000);
}
bootstrap();
// http-exception.filter.ts
import {
ArgumentsHost,
Catch,
ExceptionFilter,
HttpException,
} from '@nestjs/common';
import { Response } from 'express';
@Catch(HttpException)
export class HttpExceptionFilter<T extends HttpException>
implements ExceptionFilter
{
catch(exception: T, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const status = exception.getStatus();
const exceptionResponse = exception.getResponse();
const error =
typeof response === 'string'
? { message: exceptionResponse }
: (exceptionResponse as object);
response.status(status).json({
...error,
timestamp: new Date().toISOString(),
});
}
}