diff --git a/backend/src/common/filters/all-exceptions.filter.ts b/backend/src/common/filters/all-exceptions.filter.ts index e0a7697..d861809 100644 --- a/backend/src/common/filters/all-exceptions.filter.ts +++ b/backend/src/common/filters/all-exceptions.filter.ts @@ -4,6 +4,7 @@ import { ArgumentsHost, HttpException, HttpStatus, + Logger, } from '@nestjs/common'; import { Request, Response } from 'express'; @@ -13,17 +14,11 @@ import { Request, Response } from 'express'; * @description * HTTP 예외뿐만 아니라 모든 예외를 잡아서 처리합니다. * 예상치 못한 에러도 일관된 형식으로 응답합니다. - * - * @example - * // main.ts에서 전역 적용 - * app.useGlobalFilters(new AllExceptionsFilter()); - * - * @export - * @class AllExceptionsFilter - * @implements {ExceptionFilter} */ @Catch() export class AllExceptionsFilter implements ExceptionFilter { + private readonly logger = new Logger('ExceptionFilter'); + catch(exception: unknown, host: ArgumentsHost) { const ctx = host.switchToHttp(); const response = ctx.getResponse(); @@ -33,7 +28,6 @@ export class AllExceptionsFilter implements ExceptionFilter { let message: string | string[]; if (exception instanceof HttpException) { - // HTTP 예외 처리 status = exception.getStatus(); const exceptionResponse = exception.getResponse(); @@ -45,12 +39,10 @@ export class AllExceptionsFilter implements ExceptionFilter { message = exception.message; } } else { - // 예상치 못한 에러 처리 status = HttpStatus.INTERNAL_SERVER_ERROR; message = '서버 내부 오류가 발생했습니다.'; - // 개발 환경에서는 실제 에러 메시지 표시 - if (process.env.NODE_ENV === 'development' && exception instanceof Error) { + if (exception instanceof Error) { message = exception.message; } } @@ -64,16 +56,37 @@ export class AllExceptionsFilter implements ExceptionFilter { message: Array.isArray(message) ? message : [message], }; - // 개발 환경에서는 스택 트레이스 포함 - if (process.env.NODE_ENV === 'development' && exception instanceof Error) { + // 스택 트레이스 포함 + if (exception instanceof Error) { (errorResponse as any).stack = exception.stack; } - // 에러 로깅 - console.error( - `[${errorResponse.timestamp}] ${request.method} ${request.url} - ${status}`, - exception, + // ========== 상세 로깅 ========== + this.logger.error( + `========== EXCEPTION ==========` ); + this.logger.error( + `[${request.method}] ${request.url} - Status: ${status}` + ); + this.logger.error( + `Message: ${JSON.stringify(message)}` + ); + + if (exception instanceof Error) { + this.logger.error(`Error Name: ${exception.name}`); + this.logger.error(`Error Message: ${exception.message}`); + this.logger.error(`Stack Trace:\n${exception.stack}`); + } else { + this.logger.error(`Exception: ${JSON.stringify(exception)}`); + } + + // Request Body 로깅 (민감정보 마스킹) + const safeBody = { ...request.body }; + if (safeBody.password) safeBody.password = '****'; + if (safeBody.token) safeBody.token = '****'; + this.logger.error(`Request Body: ${JSON.stringify(safeBody)}`); + + this.logger.error(`===============================`); response.status(status).json(errorResponse); }