12
11

More than 3 years have passed since last update.

[Python]FastAPI エラーハンドリング方法 メモ

Posted at
  • 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

参考情報

12
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11