-------------------------------------------------------------
FastAPI 세 가지 에러 핸들링 방법
-------------------------------------------------------------
[출처] https://python.plainenglish.io/3-ways-to-handle-errors-in-fastapi-that-you-need-to-know-e1199e833039
1. 기본 HTTPException 이용하기
----------------------------------
fastapi 모듈에 기본으로 사용할 수 있으며, import 한 후에 raise를 이용하여 호출한다.
1) from fastapi import FastAPI, HTTPException
2) raise HTTPException(status_code = 204, detail = "")
기본적으로 “status_code”와 “detail” 항목이 있다.
“status_code”에는 HTTP status를 넣는대 200, 204, 404, 500 등이 이용된다.
“detail”에는 관련된 응답 메시지를 넣는다.
test_database = {
"12345": "User1",
"23456": "User2",
"34567": "User3",
"45678": "User4"
}
if id in test_database:
print("Found it!!")
return id
else:
raise HTTPException(status_code = 404, detail= "Id not found")
[결과 메시지]
{
"detail": "Id not found"
}
2. 사용자 Exception 만들어 이용하기
---------------------------------------
HTTPException 처리 기능이 부족하면 직접 사용자 에러를 만들어 사용한다.
먼저 아래처럼 두 모듈을 import해야 한다.
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
그후에 사용자 예외 클래스 객체를 만든다.
class MyCustomException(Exception):
def __init__(self, name: str):
self.name = name
이제 예외 핸들러를 만들고 우리 클래스 객체에 전달한다.
@app.exception_handler(MyCustomException)
async def MyCustomExceptionHandler(request: Request, exception: MyCustomException):
return JSONResponse (status_code = 500,
content = {"message": "Something critical happened"})
에러가 발생하고 예외가 발생하면 상태 코드는 500이 되고 메시지를 출력하게 된다.
@app.get("/testapi/v1/{triggererror}")
async def GetTestException(triggererror: str):
if triggererror == "yes":
raise MyCustomException(name = triggererror)
return results
[결과 메시지]
{
"message": "Something critical happened"
}
3. HTTPException 오버라이드
HttpException 예외를 오버라이드하는 방법도 가능하다.
일단 아래 두줄처럼 import 한다.
from fastapi.responses import PlainTextResponse
from starlette.exceptions import HTTPException as StarletteHTTPException
그 후에 예외를 오버라이드하는 예외 핸들러를 만든다.
@app.exception_handler(StarletteHTTPException)
async def my_exception_handler(request, exception):
return PlainTextResponse(str(exception.detail),
status_code = exception.status_code)
이 핸들러는 예외를 오버라이드하고 JSON 대신에 평문을 돌려준다.
[결과 화면]
Critical error occurred.
================== ===================================
[참고] If you provide a custom model, the OpenAPI specs will pick them up.
---------------------------------------------------------------------------------
@app.post( "/cookies", status_code=201,
responses={ 201: {"model": MyCustomOutputModel},
422: {"model": MyValidationModel},
500: {"model": UnexpectedServerError}, }, include_in_schema=True, )
=======================================================
Fast API Handling Errors
[출처] https://lucky516.tistory.com/101
HTTP Exception
------------------
HTTPException 클래스를 이용하면 에러를 일으킬 수 있다.
예제는 접근하려는 아이템이 없을 경우 404 에러를 일이키는 코드이다.
from fastapi import FastAPI, HTTPException
app = FastAPI()
items = {"foo": "The Foo Wrestlers"}
@app.get("/items/{item_id}")
async def read_item(item_id: str):
if item_id not in items:
raise HTTPException(status_code=404, detail="Item not found")
return {"item": items[item_id]}
HTTPException은 파이썬 exception에 api 관련 정보를 추가한 exception이라 raise 이용한다.
예외 발생 시 리퀘스트는 종료되며(이후 코드 무시) 클라이언트에 HTTP error를 전달한다.
(예) foo 존재하여 성공한 경우(http://example.com/items/foo), 결과 메시지
{
"item": "The Foo Wrestlers"
}
(예) bar가 없어서 실패한 경우(http://example.com/items/bar), 결과 메시지
{
"detail": "Item not found"
}
커스텀 헤더 추가하기
------------------------
HTTP error에 커스텀 헤더를 추가할 수 있다. 보안 문제로 이것을 이용하면 유용하다.
from fastapi import FastAPI, HTTPException
app = FastAPI()
items = {"foo": "The Foo Wrestlers"}
@app.get("/items-header/{item_id}")
async def read_item_header(item_id: str):
if item_id not in items:
raise HTTPException( status_code=404, detail="Item not found",
headers={"X-Error": "There goes my error"}, )
return {"item": items[item_id]}
커스텀 예외 만들기
---------------------
커스텀 예외를 만드는 방법은 아래와 같다
1) Exception을 상속하는 클래스를 만든다.
2) @app.exception_handler() 데코레이션을 사용하여 handler를 등록한다.
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
class UnicornException(Exception):
def __init__(self, name: str):
self.name = name
app = FastAPI()
@app.exception_handler(UnicornException)
async def unicorn_exception_handler(request: Request, exc: UnicornException):
return JSONResponse( status_code=418,
content={"message": f"Oops! {exc.name} did something."}, )
@app.get("/unicorns/{name}")
async def read_unicorn(name: str):
if name == "yolo":
raise UnicornException(name=name)
return {"unicorn_name": name}
'FastAPI' 카테고리의 다른 글
Nginx로 FastAPI 배포하기 (0) | 2022.01.25 |
---|---|
FastAPI 시작, 중지, 재시작 (2) | 2022.01.25 |
gunicorn 설정 (0) | 2022.01.12 |
FastAPI 서버 API 버전 관리 (0) | 2022.01.10 |
FastAPI + HTTPS (Windows) (0) | 2021.12.30 |