mcpField
E
error-handling-patterns

error-handling-patterns

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

error-handling-patterns について

アプリケーション、API、分散システムのエラー処理を支援するスキルです。エラー方式の選択、復旧、診断、代表的な対処パターンを扱います。

主な機能

  1. 01例外と Result 型の比較
  2. 02復旧可能・致命的エラーの分類
  3. 03リトライとサーキットブレーカーの適用
  4. 04コンテキストの保持とリソース解放

活用シーン

  1. 01障害に強い API の設計
  2. 02本番環境の障害調査
  3. 03非同期エラーの処理
  4. 04ユーザー向けエラーメッセージの改善

インストール

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

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

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

同梱ファイルreferences/details.md

詳細

エラーハンドリングのパターン

堅牢なエラーハンドリング戦略で、障害を適切に処理し、優れたデバッグ体験を提供する復元力のあるアプリケーションを構築します。

このスキルを使う場面

  • 新機能にエラーハンドリングを実装するとき
  • エラーに強い API を設計するとき
  • 本番環境の問題をデバッグするとき
  • アプリケーションの信頼性を向上させるとき
  • ユーザーと開発者にとってより良いエラーメッセージを作成するとき
  • リトライとサーキットブレーカーのパターンを実装するとき
  • 非同期・並行処理のエラーを処理するとき
  • フォールトトレラントな分散システムを構築するとき

中核となる概念

1. エラーハンドリングの思想

例外 vs Result 型:

  • 例外: 従来の try-catch、制御フローを乱す
  • Result 型: 成功・失敗を明示、関数型のアプローチ
  • エラーコード: C 言語スタイル、規律が必要
  • Option/Maybe 型: null 許容値向け

それぞれを使う場面:

  • 例外: 予期しないエラー、例外的な状況
  • Result 型: 想定内のエラー、バリデーションの失敗
  • パニック・クラッシュ: 回復不能なエラー、プログラミングのバグ
2. エラーの分類

回復可能なエラー:

  • ネットワークタイムアウト
  • ファイルの欠落
  • 不正なユーザー入力
  • API のレート制限

回復不能なエラー:

  • メモリ不足
  • スタックオーバーフロー
  • プログラミングのバグ(null ポインタなど)

詳細なパターンと実例

詳細なパターンのドキュメントは references/details.md にあります。上記のナビゲーション階層では不十分な場合は、そのファイルを読んでください。

ベストプラクティス

  1. 早期に失敗する: 入力を早く検証し、素早く失敗する
  2. コンテキストを保持する: スタックトレース、メタデータ、タイムスタンプを含める
  3. 意味のあるメッセージ: 何が起きたか、どう修正するかを説明する
  4. 適切にログを取る: エラー = ログに記録、想定内の失敗 = ログを溢れさせない
  5. 適切なレベルで処理する: 意味のある処理ができる場所でキャッチする
  6. リソースをクリーンアップする: try-finally、コンテキストマネージャー、defer を使う
  7. エラーを握りつぶさない: ログに記録するか再スローする、黙って無視しない
  8. 型安全なエラー: 可能な場合は型付きエラーを使う
# Good error handling example
def process_order(order_id: str) -> Order:
    """Process order with comprehensive error handling."""
    try:
        # Validate input
        if not order_id:
            raise ValidationError("Order ID is required")

        # Fetch order
        order = db.get_order(order_id)
        if not order:
            raise NotFoundError("Order", order_id)

        # Process payment
        try:
            payment_result = payment_service.charge(order.total)
        except PaymentServiceError as e:
            # Log and wrap external service error
            logger.error(f"Payment failed for order {order_id}: {e}")
            raise ExternalServiceError(
                f"Payment processing failed",
                service="payment_service",
                details={"order_id": order_id, "amount": order.total}
            ) from e

        # Update order
        order.status = "completed"
        order.payment_id = payment_result.id
        db.save(order)

        return order

    except ApplicationError:
        # Re-raise known application errors
        raise
    except Exception as e:
        # Log unexpected errors
        logger.exception(f"Unexpected error processing order {order_id}")
        raise ApplicationError(
            "Order processing failed",
            code="INTERNAL_ERROR"
        ) from e

よくある落とし穴

  • 範囲が広すぎるキャッチ: except Exception はバグを隠す
  • 空の catch ブロック: エラーを黙って握りつぶす
  • ログを取って再スロー: ログエントリが重複する
  • クリーンアップしない: ファイルや接続を閉じ忘れる
  • 不十分なエラーメッセージ: 「エラーが発生しました」は役に立たない
  • エラーコードを返す: 例外か Result 型を使う
  • 非同期エラーの無視: 未処理の Promise の reject

コメント