오류 처리

심준석·2024년 5월 6일
0

FastAPI

목록 보기
10/11

요청이 알 수 없는 오류 메시지를 그대로 노출하면 클라이언트 입장에서는 오류의 원인을 파악하기 어려울 수 있다.

존재하지 않는 리소스나 권한이 없는 페이지에 접근하는 경우 요청 시 오류가 발생하며 서버 자체에서 오류가 발생하기도 한다.

FastAPI에서 오류는 FastAPI의 HTTPException 클래스를 사용해 예외를 발생시켜 처리한다.

HTTP 예외
HTTP 예외는 요청 흐름상에 발생하는 오류나 문제를 가리키는 이벤트

HTTPException 클래스는 다음 세 개의 인수를 받는다

  • status_code : 예외 처리 시 반환할 상태 코드
  • detail : 클라이언트에게 전달할 메시지
  • headers : 헤더를 요구하는 응답을 위한 선택적 인수

존재하지 않는 todo를 추출하면 404가 아닌 200 응답이 반환된다.

HTTPException 클래스를 사용해 라우트를 변경하면 적절한 응답 코드와 함께 상태 메시지도 반환할 수 있다. todo.py에서 추출, 변경, 삭제 라우트를 다음과 같이 변경하자.

from fastapi import APIRouter, Path, HTTPException, status

...

@todo_router.get("/todo/{todo_id}")
async def get_single_todo(todo_id: int =Path(..., title="The ID of the todo to retrieve")) -> dict:
    for todo in todo_list:
        if todo.id == todo_id:
            return {
                "todo":todo
            }
    raise HTTPException(
        status_code=status.HTTP_404_NOT_FOUND,
        detail="Todo with supplied ID doesn't exist"
    )


@todo_router.put("/todo/{todo_id}")
async def update_todo(todo_data: TodoItem, todo_id: int = Path(..., title="The ID of the todo to be updated")) -> dict:
    for todo in todo_list:
        if todo.id == todo_id:
            todo.item = todo_data.item
            return {
                "message" : "Todo updated successfully"
            }
    raise HTTPException(
        status_code=status.HTTP_404_NOT_FOUND,
        detail="Todo with supplied ID doesn't exist"
    )

@todo_router.delete("/todo/{todo_id}")
async def delete_single_todo(todo_id: int) -> dict:
    for index in range(len(todo_list)):
        todo = todo_list[index]
        if todo_id == todo_id:
            todo_list.pop(index)
            return {
                "message" : "Todo deleted successfully"
            }
    raise HTTPException(
        status_code=status.HTTP_404_NOT_FOUND,
        detail="Todo with supplied ID doesn't exist"
    )

이제 다시 한번 존재하지않는 todo를 추출해주자.

마지막으로 데코레이터 함수에 status_code 인수를 추가해 기본 응답 코드(200)를 다른 코드로 변경해보자.

@todo_router.post("/todo", status_code=201)
async def add_todo(todo: Todo) -> dict:
    todo_list.append(todo)
    return {
        "message":"Todo added successfully!"
    }

참고로 요청 성공을 의미하는 기본 상태 코드는 200이다.

profile
Developer & Publisher 심준석 입니다.

0개의 댓글