mcpField
P
python-error-handling

python-error-handling

github.com/wshobson開発41.9k14.3k 回インストール2 週間前に更新
リポジトリ

python-error-handling について

python-error-handling は、Python 開発者向けに入力検証、例外設計、障害時の処理を扱うスキルです。デバッグ情報の維持や、バッチ処理での部分的な失敗への対応も取り上げます。

主な機能

  1. 01早期の入力検証
  2. 02状況が分かる例外の設計
  3. 03外部データのドメイン型への変換
  4. 04例外チェーンの保持
  5. 05バッチ処理の部分的な失敗への対応
  6. 06Pydantic による複雑な入力検証

活用シーン

  1. 01ユーザー入力と API パラメーターの検証
  2. 02アプリケーションの例外階層の設計
  3. 03バッチ処理の失敗への対応
  4. 04ユーザー向けエラーメッセージの作成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/wshobson/agents --skill python-error-handling

インストール後、Claude Code で/python-error-handlingを入力して読み込まれたか確認します。

同梱ファイルreferences/details.md

詳細

Python のエラー処理

適切な入力検証、意味のある例外、および優雅な失敗処理を備えた堅牢な Python アプリケーションを構築します。優れたエラー処理は、デバッグを容易にし、システムの信頼性を高めます。

このスキルを使用する場面

  • ユーザー入力と API パラメータを検証するとき
  • アプリケーションの例外階層を設計するとき
  • バッチ操作における部分的な失敗を処理するとき
  • 外部データをドメイン型に変換するとき
  • ユーザーフレンドリーなエラーメッセージを構築するとき
  • フェイルファスト検証パターンを実装するとき

中核となる概念

1. フェイルファスト

負荷の高い操作の前に、入力を早期に検証します。可能であれば、すべての検証エラーを一度に報告します。

2. 意味のある例外

コンテキストを伴う適切な例外型を使用します。メッセージは、何が失敗したのか、なぜ失敗したのか、どのように修正するのかを説明する必要があります。

3. 部分的な失敗

バッチ操作では、1 つの失敗で全体を中断させないようにします。成功と失敗を別々に追跡します。

4. コンテキストの保持

デバッグのために完全なエラーの軌跡を維持するよう、例外を連鎖させます。

クイックスタート

def fetch_page(url: str, page_size: int) -> Page:
    if not url:
        raise ValueError("'url' is required")
    if not 1 <= page_size <= 100:
        raise ValueError(f"'page_size' must be 1-100, got {page_size}")
    # Now safe to proceed...

基本的なパターン

パターン 1: 早期の入力検証

処理を開始する前に、API 境界ですべての入力を検証します。

def process_order(
    order_id: str,
    quantity: int,
    discount_percent: float,
) -> OrderResult:
    """Process an order with validation."""
    # Validate required fields
    if not order_id:
        raise ValueError("'order_id' is required")

    # Validate ranges
    if quantity <= 0:
        raise ValueError(f"'quantity' must be positive, got {quantity}")

    if not 0 <= discount_percent <= 100:
        raise ValueError(
            f"'discount_percent' must be 0-100, got {discount_percent}"
        )

    # Validation passed, proceed with processing
    return _process_validated_order(order_id, quantity, discount_percent)
パターン 2: 早期にドメイン型へ変換する

システム境界で、文字列や外部データを型付きのドメインオブジェクトに解析します。

from enum import Enum

class OutputFormat(Enum):
    JSON = "json"
    CSV = "csv"
    PARQUET = "parquet"

def parse_output_format(value: str) -> OutputFormat:
    """Parse string to OutputFormat enum.

    Args:
        value: Format string from user input.

    Returns:
        Validated OutputFormat enum member.

    Raises:
        ValueError: If format is not recognized.
    """
    try:
        return OutputFormat(value.lower())
    except ValueError:
        valid_formats = [f.value for f in OutputFormat]
        raise ValueError(
            f"Invalid format '{value}'. "
            f"Valid options: {', '.join(valid_formats)}"
        )

# Usage at API boundary
def export_data(data: list[dict], format_str: str) -> bytes:
    output_format = parse_output_format(format_str)  # Fail fast
    # Rest of function uses typed OutputFormat
    ...
パターン 3: 複雑な検証には Pydantic を使用する

自動エラーメッセージを備えた構造化された入力検証には、Pydantic モデルを使用します。

from pydantic import BaseModel, Field, field_validator

class CreateUserInput(BaseModel):
    """Input model for user creation."""

    email: str = Field(..., min_length=5, max_length=255)
    name: str = Field(..., min_length=1, max_length=100)
    age: int = Field(ge=0, le=150)

    @field_validator("email")
    @classmethod
    def validate_email_format(cls, v: str) -> str:
        if "@" not in v or "." not in v.split("@")[-1]:
            raise ValueError("Invalid email format")
        return v.lower()

    @field_validator("name")
    @classmethod
    def normalize_name(cls, v: str) -> str:
        return v.strip().title()

# Usage
try:
    user_input = CreateUserInput(
        email="[email protected]",
        name="john doe",
        age=25,
    )
except ValidationError as e:
    # Pydantic provides detailed error information
    print(e.errors())
パターン 4: エラーを標準例外にマッピングする

必要に応じてコンテキストを追加しながら、Python の組み込み例外型を適切に使用します。

失敗の種類例外例
無効な入力ValueError不正なパラメータ値
型の誤りTypeError文字列を期待したが int を受け取った
項目の欠落KeyError辞書のキーが見つからない
操作の失敗RuntimeErrorサービスが利用不可
タイムアウトTimeoutError操作に時間がかかりすぎた
ファイルが見つからないFileNotFoundErrorパスが存在しない
アクセス許可が拒否されたPermissionErrorアクセスが禁止されている
# Good: Specific exception with context
raise ValueError(f"'page_size' must be 1-100, got {page_size}")

# Avoid: Generic exception, no context
raise Exception("Invalid parameter")

詳細な実例とパターン

詳細なセクション(## Advanced Patterns で始まるもの)は references/details.md にあります。上記のナビゲーション概要では不十分な場合は、そのファイルをお読みください。

ベストプラクティスのまとめ

  1. 早期に検証する - 負荷の高い操作の前に入力を確認する
  2. 具体的な例外を使用する - 汎用的な Exception ではなく、ValueError、TypeError を使用する
  3. コンテキストを含める - メッセージは、何を、なぜ、どのように修正するのかを説明する必要がある
  4. 境界で型を変換する - 文字列を早期に enum やドメイン型に解析する
  5. 例外を連鎖させる - raise ... from e を使用してデバッグ情報を保持する
  6. 部分的な失敗を処理する - 単一項目のエラーでバッチを中断しない
  7. Pydantic を使用する - 構造化されたエラーを伴う複雑な入力検証に使用する
  8. 失敗モードを文書化する - docstring に発生しうる例外を列挙する
  9. コンテキストを伴ってログに記録する - ID、件数、その他のデバッグ情報を含める
  10. エラーパスをテストする - 例外が正しく発生することを検証する

コメント