작성
·
270
0
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
} from '@nestjs/common';
import { Request, Response } from 'express';
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
const status = exception.getStatus();
const error = exception.getResponse() as
| string
| { error: string; statusCode: number; message: string | string[] };
if (typeof error === 'string') {
response.status(status).json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
message: error,
});
} else {
response.status(status).json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
message: error,
});
}
}
}
안녕하세요 ! 위와 같이 필터 작성이후
main.ts 에서
app.useGlobalFilter(new HttpExceptionFilter());
를 통해 예외가 잘 잡히는것을 확인을 했었습니다.
왜인지는 모르겠으나 cat의 모델 내부 필드중에 imgUrl 부분을 null 을 허용해주기 위해
@IsOptional() 을 붙여주고난 뒤에
중복 회원가입을 진행하려 할 경우 예외에 잡히게끔 하려 HttpException 을 발생 시키게끔 했습니다.
async signUp(body: CatRequestDTO): Promise<Cat> {
const email = body.email;
const checkExist = await this.catRepository.findOne({ where: { email } });
if (!checkExist) {
const createdCat = this.catRepository.create(body);
this.catRepository.save(createdCat);
return createdCat;
} else {
throw new HttpException(
'Already exist Email in DB',
HttpStatus.BAD_REQUEST,
);
}
}
콘솔창에 에러 메세지와 함께 출력되는것은 확인되나
Filter에서 exception @Catch 로 묶어준것에 잡히지를 않습니다.
도통 이유를 못찾겠어서 app.useGlobalFilter(...) 를
catController 쪽에 @UseFilters(new HttpExceptionFilter()) 로도 바꿔보고
메서드에다가 직접적으로도 붙여보았으나 계속 똑같은 현상을 보이는데
왜 인지를 못잡겠습니다. 조언을 좀 주시면 감사하겠습니다.
답변 1
1
안녕하세요, 인프런 AI 인턴이에요.
exception filter를 사용하면 예외를 잡을 수 있지만, imgUrl 필드에서 null을 허용하기 위해 @IsOptional()을 사용한 후 중복 회원 가입 예외가 잡히지 않는다는 문제가 있으시군요.
이 문제는 @IsOptional() 데코레이터가 예외 필터링되지 않아 발생하는 것으로 보입니다. @IsOptional()은 데이터 유효성 검사를 수행하는 class-validator의 기능인데, 이 기능이 예외 필터링과 충돌하는 것 같아요.
해결 방법으로는 imgUrl 필드에 @IsOptional() 대신 데이터 유효성 검사를 직접 수행하는 코드를 추가하는 것입니다. try-catch 문을 사용하여 imgUrl이 null이면 예외를 발생시키고, 이 예외를 HttpException으로 변환하여 필터에 잡히도록 처리하면 될 것 같아요. 아래는 예시 코드입니다.
class YourModel {
// ...
@ApiPropertyOptional()
@IsString()
imgUrl: string | null;
// ...
}
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
const status = exception.getStatus();
const error = exception.getResponse() as
| string
| { error: string; statusCode: number; message: string | string[] };
if (typeof error === 'string') {
response.status(status).json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
message: error,
});
} else {
response.status(status).json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
message: error,
});
}
}
}
// ...
try {
// imgUrl이 null인 경우 예외 발생
if (yourModel.imgUrl === null) {
throw new Error("imgUrl is required");
}
// ...
} catch (error) {
// 에러를 HttpException으로 변환하여 필터링되도록 처리
throw new HttpException("Invalid input data", HttpStatus.BAD_REQUEST);
}
이렇게 하면 imgUrl 필드가 null인 경우 예외가 발생하고, HttpExceptionFilter에서 이 예외를 잡아 처리할 수 있을 겁니다. 참고로 위 코드는 예시이므로 실제 상황에 맞게 적절히 수정해야 합니다.
혹시 다른 문제가 발생하거나 추가적인 도움이 필요하시면 언제든지 물어보세요. 도움이 됐길 바랄게요.
너무 감사합니다. 잘 해결되었어요!!