エラーハンドラーの設定をすることで、try-except毎にレスポンスの組み立てが不要になり、コードがシンプルになると考える。
自分はこのエラーハンドラーの機能があり、助かってる。
エラーハンドラーの設定
特定のエラーに対する応答結果をカスタマイズしたい場合、@app.exception_handler
を設定する。
@app.exception_handler(ValidationError) async def handle_validation_error(request: Request, exc: ValidationError): return JSONResponse( status_code=400, content={"message": "ValidationErrorが発生したよ"} )
exception_handler
デコレータのパラメータにハンドリングするExceptionクラスを指定する。
関数のパラメータは、第一パラメータにRequest
クラス、第二パラメータには処理するExceptionクラスを指定。
最後に、返却したい応答結果をJSONResponse
クラスを使って、応答結果を設定する。
JSONResponse
クラスのstatus_code
にステータスコード、content
パラメータに応答内容を設定。
上記の場合、ステータスコードが400、応答内容にJSONのmessageキーにValidationErrorが発生したよ
の値を設定したデータを返す。
動作確認
応答結果を組み立てる際に、pydanticでValidationErrorが発生するソースコードを用意して実際に動かしてみる。
実際に、動作をさせてみると。
エラーハンドラーの設定がない場合、500エラーが返却される。
エラーハンドラーの設定がある場合、期待する応答が返却される。
最後に
このエラーハンドリングを使うことで、返却したい応答用のExceptionクラスをレイズすれば、応答結果を返すことができる。 そうすることで、try-except毎に応答結果を生成する処理は不要になり、コードがシンプルになると考える。 自分は、try-except毎に応答結果の処理を作りたくないので、エラーハンドリングの機能があって助かっている。
参考
ソースコード
pydanticのインストールも必要。
from fastapi import FastAPI, Request from fastapi.responses import JSONResponse from pydantic import BaseModel, Field, PositiveInt, RootModel, ValidationError from typing import List from logging import getLogger, StreamHandler logger = getLogger(__name__) logger.addHandler(StreamHandler()) logger.setLevel("INFO") class Product(BaseModel): id: int = Field(...) name: str = Field(...) cost : PositiveInt = 0 class Products(RootModel): root: List[Product] app = FastAPI() @app.get("/") def hello(): product = Product(id=1, name="チョコ", cost=100) products = Products.model_validate(product) return products @app.exception_handler(ValidationError) async def handle_validation_error(request: Request, exc: ValidationError): logger.info("Call Exception Handler!!") return JSONResponse( status_code=400, content={"message": "ValidationErrorが発生したよ"} )