FastAPI - Custom Exception Handler 사용하기
목차
Custom Exception과 Exception Handler
FastAPI에서 커스텀 Exception Handler를 사용하는 방법을 알아보겠습니다. FastAPI API에서 다음과 같은 코드는 에러 응답을 반환합니다. FastAPI를 처음 쓸 때 HTTPException을 그냥 사용했었는데, status code와 detail message만 전달하니 함께 일하던 프론트엔드 동료가 error를 구분하기 어렵다고 구분할 수 있도록 code도 함께 넣어 전달해달라는 요청이 있었습니다.
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail="ERROR"
)
# Status Code로 400을 전달
# {"detail":"ERROR"} 로 Response를 전달
에러응답에 더 많은걸 담고 싶을 경우
다른 데이터를 추가로 담고 싶어 간단하게 HTTPException
을 상속받아 Custom Exception을 만들었습니다.
from fastapi import HTTPException as BaseHTTPException
class HTTPException(BaseHTTPException):
def __init__(
self,
status_code: int,
detail: str = None,
code: str = None,
headers: dict = None,
):
self.code = code
super().__init__(status_code, detail, headers)
프론트엔드에 Error를 구분할 수 있는 코드를 전달하기 위해 위와 같이 HTTPException
에 code를 추가해줬습니다. 위 Status Code가 똑같은 400이어도 다른 원인이 다를 수 있기 때문에 구분할 수 있는 code를 전달해 준 것입니다.
Exception만 바꾼다고 끝이 아닙니다. FastAPI app단에서 변경된 Exception을 잘 처리할 수 있도록 handler를 만들어 주입시켜줘야 합니다.
다음과 같이 할 수 있습니다.
from fastapi import HTTPException as BaseHTTPException, Request
from fastapi.responses import JSONResponse
async def http_exception_handler(request: Request, exc: HTTPException) -> JSONResponse:
return JSONResponse(
status_code=exc.status_code,
content={"code": exc.code, "detail": exc.detail},
)
# app = FastAPI() 입니다.
app.add_exception_handler(HTTPException, http_exception_handler)
위 핸들러를 주입시켜주면 HTTPException이 발생할 때 Response에 Code를 담아서 보냅니다. 추가로 더 넣고 싶은 데이터가 있다면 handler를 Exception과 handler를 커스텀하여 추가하면 됩니다.
추가로 schema로 많이 쓰는 Pydantic에서는 Validation이 잘 못되면 422에러를 발생시키는데 이 에러도 커스텀할 수 있습니다.
from fastapi.exceptions import RequestValidationError
async def validation_exception_handler(request: Request, e: RequestValidationError):
detail = e.errors()
return JSONResponse(
content={"detail": detail[0]["msg"], "message": "Validation Fail!!!!"},
status_code=422,
)
app.add_exception_handler(RequestValidationError, validation_exception_handler)
오늘은 FastAPI에서 사용할 수 있는 Custom Exception Handler에 대해서 알아봤습니다.