기존에는 레이어와 상관없이 에러를 발생시키고 싶다면 fastAPI 에서 제공하는 HTTPException 과 status 를 사용하여 직접 에러 response 를 발생시켰다.
기존 방식의 단점
에러가 발생하는 곳이 흩어져 있어 관리가 어려움
주로 사용하는 반환하는 에러는 404, 400 인데 매번 status 를 설정해줘야함 (코드 중복)
커스텀에러 사용방법
커스텀에러 만들기
현재 프로젝트에서는 app 하위에 exceptions 패키지를 만들어 하위에 에러들을 관리하도록 했다.
Not Found 에러를 추가한다.
class NotFoundError(Exception):
detail: str
def __init__(self, detail: str) -> None:
self.detail = detail
커스텀에러 핸들러 만들기
현재 프로젝트에서는 app 하위에 exception_handler.py 를 두어 에러를 관리하도록 하였다. (이후 확장이 필요하면 패키지를 따로 두는 것이 좋을 것 같다.)
Not Found 에러를 캐치하여 404 코드와 메시지를 반환하도록 핸들러를 추가한다.
from fastapi import Request, status
from fastapi.responses import ORJSONResponse
from app.exceptions.not_found import NotFoundError
async def handle_not_found_error(request: Request, exc: NotFoundError):
return ORJSONResponse(
status_code=status.HTTP_404_NOT_FOUND,
content={"detail": exc.detail},
)
커스텀에러 핸들러 FastAPI 앱에 등록하기
app 의 main.py 에서 기존 app 에 add_exception_handler 메서드를 통해 핸들러를 등록한다.
def create_app() -> FastAPI:
app_ = FastAPI(
title=settings.PROJECT_NAME,
version=settings.VERSION,
description=make_description(),
default_response_class=ORJSONResponse,
middleware=make_middlewares(),
)
init_routers(app_)
app_.add_exception_handler(NotFoundError, handle_not_found_error)
app_.add_exception_handler(BadRequestError, handle_bad_request_error)
return app_
참고. 데코레이터를 통한 핸들러 등록하는 방법도 있지만, 핸들러가 많아질 경우 알아보기 힘들기 때문에 분리하였다.