Fast API 예외처리

SeungjaeHan·2023년 4월 13일
0

FastAPI 도입기

목록 보기
2/2

fastapi 사용 도중 예외처리를 스마트하게 할 수 있는 방법에 대해 고민해보았다.
보통 Backend 로직을 작성하다보면 MVC패턴에서 예외처리를 하게 되는데 try except를 덕지덕지 발라놓게 되면 python내에서 코드가 줄맞춤때문에 보기 힘들어지는 경우가 생깁니다.

try:
	"""codes"""
except CustomException1 as e
	"""exception errors"""
except Exception as e
	"""errors"""

이런 코드들이 로직 중간에 듬성 듬성 들어가면 보기 싫어지고 또 어떤 상황에 특정 Exception을 걸기가 힘들어지는 현상도 일어난다.

FastAPI Exception

fastapi에는 Exception을 Handling 할 수 있는 가이드가 존재합니다.
https://fastapi.tiangolo.com/tutorial/handling-errors/
가이드를 살펴보면 Exception에 해당하는 클래스를 만들어서 Handling에 사용합니다.

class InvalidUserId(Exception):
    def __init__(self, user_id: str):
        self.user_id: str = user_id
        
---------------------------------------------------------------        
        
from .model import UserInfoRequest
from fastapi.responses import JSONResponse
from app.modules.errors import InvalidUserId


async def get_user_info(user_info_request: UserInfoRequest):
    if user_info_request.user_id == "test_user_info":
        return JSONResponse(user_info_request.dict())
    else:
        raise InvalidUserId(user_id=user_info_request.user_id)

---------------------------------------------------------------

from fastapi.responses import JSONResponse
from app.modules.errors import InvalidUserId


@app.exception_handler(InvalidUserId)
async def invalid_user_id_exception_handler(request: Request, exc: InvalidUserId):
    return JSONResponse(
        status_code=status.HTTP_400_BAD_REQUEST,
        content={
            "content": "invalid user id",
            "user_id": exc.user_id
        }
    )

해당 클래스를 만들고 raise를 이르키면 invalid_user_id_exception_handler로 넘어가게 됩니다.

test_user_info 를 user_id로 작성하게 된다면 정상적인 response를 반환하게 될 것이고 이외의 user_id를 요청하게 된다면 exception_handler에 작성 된 것처럼 나와야 할 것입니다.



fastapi에서 기본적으로 swagger를 제공하기 때문에 편리하게 테스트 해볼 수 있습니다.

위 스크린샷처럼 예측되어진 에러로 나타나게 될 것입니다. error handler를 디버깅을 해보겠습니다.

raise가 발생되었고 이 뒤는 error_handler로 넘거갈 것입니다.

예상대로 exception_handler에 넣어준 error class의 에러가 나왔을시 지정된 error handler로 넘어갔고 fast api의 작동방법에 따라 exc안에 class instance가 존재해야 합니다.

위와 같이 exc에는 error class가 존재하고 잘 전달되는 것으로 확인이 됩니다.

exception_handler를 써야하는 이유

보통 service logic에서 error handlering이 필요하다. 이때 try: except:이나 함수에서 return으로 에러관련 class 혹은 값들을 내어주면 function과 class에서 한 가지 type의 값을 return 해주는 것이 아닌 여러 에러 값까지 내어주게 됩니다. python type hint로 return 값을 지정해주는 경우 이런 것들을 Union (3.10부터는 | 로도 가능합니다.) 으로 값을 지정해줘야 합니다. 이런경우 쓸 때 없이 코드가 길어지겠죠.
이런 경우 보통 raise를 사용하고 최외곽에서 try except으로 관리를 하게 됩니다. 하지만 이런 경우도 api를 만들때 api route 마다, controller(http method)마다 try: except:를 만들어 주어야겠죠.(다른방법이 있으면 공유 부탁드립니다!)
fastapi의 exception handler를 사용하게 되면 이런 경우들(모든 api)을 한거번에 처리가 가능하고 raise가 되는 error class instance를 생성 해서 error handlering에 반환 할 수 있고 이를 response 혹은 여러 로직들을 handler에 넣을 수 있겠습니다. 이런경우 편리해지겠죠.

예시코드 : https://github.com/seungjae08/fast-api-template

fastapi를 사용해 프로젝트를 구성할 때 더 많은 구성방법에 대해 앞으로도 계속해서 글을 작성해보겠습니다.

profile
Front End Developer 한승재입니다.

0개의 댓글

관련 채용 정보