Skip to content
閲覧中:
バリデーション3

バリデーション3

バリデーションエラーをユーザーに返す際、最も重要なのは**「どこが(Where)」「なぜ(Why)」間違っているかを、機械ではなく人間が理解できる言葉で伝えること**です。

PydanticとFastAPIなどのモダンな構成を例に、具体的なエラーハンドリングの実装パターンを紹介します。


1. 良いエラーレスポンスの構造

APIから返すエラーは、以下のような構造にするとフロントエンド(JavaScriptなど)側で処理しやすくなり、ユーザーへの表示もスムーズになります。

JSON
{
  "status": "error",
  "message": "入力内容に不備があります。",
  "details": [
    {
      "field": "quantity",
      "reason": "must_be_positive",
      "message": "数量は1以上にしてください。"
    },
    {
      "field": "contact_email",
      "reason": "invalid_format",
      "message": "有効なメールアドレスを入力してください。"
    }
  ]
}

2. Pythonでの実装例(Pydanticのエラーを変換)

Pydanticが発生させるエラー(ValidationError)をそのまま返すと、英語のメッセージや内部的なパスが含まれてしまい、一般ユーザーには不親切です。これを「翻訳・整形」するロジックをスタブ的に作成します。

Python
from pydantic import ValidationError

def format_pydantic_errors(e: ValidationError):
    """
    Pydanticのエラーオブジェクトを、フロントエンド用のわかりやすい辞書形式に変換する
    """
    error_details = []
    for error in e.errors():
        # error['loc'] は ('quantity',) のようなタプル
        field_name = error['loc'][0]

        # エラータイプに応じて日本語メッセージを割り当て(簡易版)
        raw_msg = error['msg']
        friendly_msg = "入力内容が正しくありません"

        if "greater than 0" in raw_msg:
            friendly_msg = "1以上の数字を入力してください。"
        elif "value is not a valid email" in raw_msg:
            friendly_msg = "メールアドレスの形式が正しくありません。"
        elif "field required" in raw_msg:
            friendly_msg = "この項目は必須です。"

        error_details.append({
            "field": field_name,
            "message": friendly_msg
        })

    return {
        "status": "validation_error",
        "errors": error_details
    }

3. ユーザーインターフェース(UI)への反映

バックエンドから返ってきたエラーメッセージを、画面上のどこに表示するかが重要です。

  • インライン表示: 各入力項目のすぐ下に赤い文字で表示する(最も推奨)。
  • トースト通知: 画面の隅に一時的に「保存に失敗しました」と出す(補助的)。
  • サマリー表示: フォームの最上部にエラー内容を箇条書きで出す。

4. 5,000行規模での「エラーハンドリング」の工夫

この規模のプロジェクトでは、エラー処理を各所にバラバラに書くとコードが肥大化します。

  1. 共通例外クラスの作成: AppError のような独自のベースクラスを定義する。
  2. グローバルなエラーキャッチャー: Webフレームワークの機能(Middlewareなど)を使い、どこでエラーが起きても同じ形式のレスポンスが返るように共通化する。
  3. 多言語対応(i18n): メッセージをコード内に直接書かず、messages.yaml などの外部ファイルに切り出す。

次のステップへの提案

エラーハンドリングを共通化する**「ミドルウェア(Middleware)」や「例外ハンドラ(Exception Handler)」の具体的な書き方**について興味はありますか?

あるいは、実際のアプリ開発において、「エラーが起きたことをログに残して開発者に通知する方法」(Sentryなどのツール活用)についてお話ししましょうか?