요청이 알 수 없는 오류 메시지를 그대로 노출하면 클라이언트 입장에서는 오류의 원인을 파악하기 어려울 수 있다.
존재하지 않는 리소스나 권한이 없는 페이지에 접근하는 경우 요청 시 오류가 발생하며 서버 자체에서 오류가 발생하기도 한다.
FastAPI에서 오류는 FastAPI의 HTTPException 클래스를 사용해 예외를 발생시켜 처리한다.
HTTP 예외
HTTP 예외는 요청 흐름상에 발생하는 오류나 문제를 가리키는 이벤트
HTTPException 클래스는 다음 세 개의 인수를 받는다
존재하지 않는 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이다.