- FastAPIのエラーハンドリング方法についてメモする。
- 指定したキーが存在しないケースでエラーハンドリングパターンを検証してみる。
①HTTPExceptionを利用するケース
- HTTPExceptionを利用する。
from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponse
from fastapi.responses import PlainTextResponse
from starlette.exceptions import HTTPException as StarletteHTTPException
app = FastAPI()
items = {"1": "test_item"}
@app.get("/testapi/http_exception/items/{item_id}")
async def get_http_exception(item_id: str):
# 指定したキーが存在しない場合
if item_id not in items:
raise HTTPException(status_code=404, detail="item_not_found")
return {"item": items[item_id]}
-
リクエスト
GET /testapi/http_exception/items/3 HTTP/1.1 Host: 127.0.0.1:8000
-
レスポンス
404 Not Found { "detail": "item_not_found" }
②独自定義したExceptionを利用するケース
- Exceptionを継承し、独自定義したエラーを返却する。
- パスパラメータとして指定された値をレスポンスボディに埋め込んだりしたい場合。
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
app = FastAPI()
items = {"1": "test_item"}
class CustomNotFoundException(Exception):
def __init__(self, item_id: str):
self.item_id = item_id
@app.exception_handler(CustomNotFoundException)
async def CustomExceptionHandler(request: Request, exception: CustomNotFoundException):
return JSONResponse(status_code=404, content={"detail": f"item_id_{exception.item_id} is_not_found"})
@app.get("/testapi/custom_exception/items/{item_id}")
async def get_custom_exception(item_id: str):
# 指定したキーが存在しない場合
if item_id not in items:
raise CustomNotFoundException(item_id=item_id)
return {"item": items[item_id]}
-
リクエスト
GET /testapi/custom_exception/items/3 HTTP/1.1 Host: 127.0.0.1:8000
-
レスポンス
404 Not Found { "detail": "item_id_3 is_not_found" }
③デフォルトExceptionハンドラーをオーバーライドするケース
- デフォルトのExceptionハンドラーをオーバーライドさせる。
- レスポンスボディをJSONではなく、text形式で返却させたい場合。
from fastapi import FastAPI, HTTPException
from fastapi.responses import PlainTextResponse
from starlette.exceptions import HTTPException as StarletteHTTPException
app = FastAPI()
items = {"1": "test_item"}
@app.exception_handler(StarletteHTTPException)
async def http_exception_handler(request, exc):
return PlainTextResponse(str(exc.detail), status_code=exc.status_code)
@app.get("/testapi/override_http_exception/items/{item_id}")
async def get_override_http_exception(item_id: str):
if item_id not in items:
raise HTTPException(
status_code=404, detail=f"item_id_{item_id}_is_not_found")
return {"item": items[item_id]}
-
リクエスト
GET /testapi/override_http_exception/items/3 HTTP/1.1 Host: 127.0.0.1:8000
-
レスポンス
404 Not Found
item_id_3_is_not_found
## 参考情報
* [Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/)