Vol.18

エラーハンドリングの設計思想

はじめに

システム開発において、エラーは必ず発生します。重要なのは、エラーをどう扱うかです。AI開発では、エラーハンドリングの設計が特に重要になります。

エラーハンドリングの目的

1. ユーザー体験の維持

✗ 悪い例:「Error: SQLITE_CONSTRAINT」
◯ 良い例:「入力内容を確認してください。メールアドレスはすでに登録されています。」

2. デバッグの容易化

// ログに記録する情報
- エラー発生日時
- エラー種別
- 発生箇所
- リクエスト内容
- スタックトレース(内部用)

3. システムの安定性

エラーが発生しても、システム全体が停止しないようにします。

エラーの分類

【予測可能なエラー】
- 入力値のバリデーションエラー
- 認証エラー
- リソースが見つからない(404)
- 権限エラー(403)
→ 適切なメッセージでユーザーに通知

【予測不能なエラー】
- データベース接続エラー
- 外部API障害
- メモリ不足
- プログラムのバグ
→ 汎用メッセージを表示し、詳細はログに記録

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

パターン1:エラーコードの統一

const ERROR_CODES = {
    // 認証系
    AUTH_REQUIRED: 'AUTH_REQUIRED',
    AUTH_INVALID_TOKEN: 'AUTH_INVALID_TOKEN',

    // バリデーション系
    VALIDATION_REQUIRED: 'VALIDATION_REQUIRED',
    VALIDATION_FORMAT: 'VALIDATION_FORMAT',

    // システム系
    SYSTEM_ERROR: 'SYSTEM_ERROR',
    DATABASE_ERROR: 'DATABASE_ERROR'
};

パターン2:レスポンス形式の統一

// 成功レスポンス
{
    "success": true,
    "data": { ... }
}

// エラーレスポンス
{
    "success": false,
    "error": {
        "code": "VALIDATION_REQUIRED",
        "message": "メールアドレスは必須です",
        "field": "email"
    }
}

セキュリティ上の注意

// ❌ 危険:詳細情報を外部に露出
{
    "error": "Error: SQLITE_CONSTRAINT: UNIQUE constraint failed..."
}

// ✅ 安全:汎用メッセージ
{
    "error": {
        "code": "RESOURCE_CONFLICT",
        "message": "このメールアドレスはすでに登録されています"
    }
}

仕様書への記載

## エラーハンドリング仕様

### 入力値エラー
- 必須項目が未入力の場合、フィールド単位でエラーメッセージを表示
- フォーマット不正の場合、正しい形式を案内

### 認証エラー
- 未ログイン:ログイン画面へリダイレクト
- トークン期限切れ:自動リフレッシュを試行

### システムエラー
- ユーザーには汎用メッセージを表示
- 詳細はサーバーログに記録

まとめ

エラーハンドリングの設計は、以下の原則に従いましょう:

  1. ユーザーには分かりやすく - 専門用語を避けた説明
  2. 開発者には詳細に - ログで十分な情報を記録
  3. 形式を統一 - エラーコード、レスポンス形式
  4. 集約して管理 - 共通ハンドラーで一元管理
  5. セキュリティに注意 - 内部情報の漏洩防止

次回:「ドキュメント駆動開発の実践」