# 機能設計書 26-Debug Exceptions

## 概要

本ドキュメントは、Ruby on Railsの例外デバッグ機能の設計仕様を定義する。Debug Exceptionsは、開発環境において例外発生時に詳細なデバッグ情報を表示するミドルウェアである。

### 本機能の処理概要

**業務上の目的・背景**：開発中のWebアプリケーションでは、エラーの原因を素早く特定することが生産性向上に直結する。Debug Exceptionsミドルウェアは、例外発生時にスタックトレース、ソースコードの該当箇所、リクエスト情報、セッション情報などを包括的に表示し、開発者が効率的にデバッグできる環境を提供する。

**機能の利用シーン**：開発環境でのエラー発生時に自動的に動作し、エラー診断画面を表示する。ルーティングエラー、テンプレートエラー、データベースエラー、アプリケーションロジックのエラーなど、あらゆる例外をキャッチして視覚的に表示する。

**主要な処理内容**：
1. 例外のキャッチとExceptionWrapperでのラップ
2. 例外インターセプターへの通知
3. エラーログへの記録
4. デバッグ用HTML/JSON/テキストレスポンスの生成
5. ソースコード抽出とスタックトレースの整形

**関連システム・外部連携**：Action View（エラーテンプレート描画）、Logger（エラーログ記録）、Routes Inspector（ルーティング情報表示）と連携する。

**権限による制御**：action_dispatch.show_detailed_exceptions ヘッダーがtrueの場合のみ詳細表示。デフォルトではローカルリクエストのみ詳細表示される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 8 | 例外診断画面 | 主機能 | 例外発生時の詳細診断情報表示処理 |
| 9 | ルーティングエラー画面 | 主機能 | RoutingError例外の捕捉・表示処理 |
| 10 | テンプレート未検出画面 | 主機能 | MissingTemplate例外の捕捉・表示処理 |
| 11 | アクション未定義画面 | 主機能 | UnknownAction例外の捕捉・表示処理 |
| 12 | ホストブロック画面 | 補助機能 | ブロック原因の説明と設定方法の案内 |
| 13 | テンプレートエラー画面 | 主機能 | テンプレート描画エラーの診断情報表示 |
| 14 | 無効なステートメント画面 | 主機能 | データベース関連エラーの診断情報表示 |
| 15 | テンプレート不正確画面 | 主機能 | インタラクティブリクエストに対するテンプレート不足エラー表示 |

## 機能種別

エラー処理 / デバッグ支援

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| exception | Exception | Yes | 発生した例外オブジェクト | - |
| env | Hash | Yes | Rack環境変数 | - |
| routes_app | Object | No | ルーティング情報を持つアプリケーション | routes に応答すること |
| response_format | Symbol | No | レスポンス形式 | :default, :api |

### 入力データソース

- Rack アプリケーションから raise された例外
- リクエスト環境（env hash）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| status_code | Integer | HTTPステータスコード |
| body | String | エラー表示用HTML/JSON/テキスト |
| content_type | String | Content-Type ヘッダー |

### 出力先

- HTTPレスポンス（ブラウザ表示）
- ログファイル（エラーログ）

## 処理フロー

### 処理シーケンス

```
1. ミドルウェアcall
   └─ @app.call(env) でリクエスト処理
2. X-Cascadeヘッダー確認
   └─ "pass"の場合はRoutingError発生
3. 例外キャッチ
   └─ ExceptionWrapperでラップ
4. インターセプター呼び出し
   └─ 登録されたインターセプターを順次実行
5. 例外レンダリング
   └─ show?で表示判定
   └─ render_exception でレスポンス生成
6. ログ出力
   └─ log_error でエラーログ記録
```

### フローチャート

```mermaid
flowchart TD
    A[call メソッド] --> B[@app.call]
    B --> C{X-Cascade: pass?}
    C -->|Yes| D[RoutingError発生]
    C -->|No| E[レスポンス返却]
    D --> F[例外キャッチ]
    B --> |例外発生| F
    F --> G[ExceptionWrapper作成]
    G --> H[インターセプター呼び出し]
    H --> I{show?}
    I -->|Yes| J[render_exception]
    I -->|No| K[例外を再raise]
    J --> L{リクエストタイプ?}
    L -->|ブラウザ| M[render_for_browser_request]
    L -->|API| N[render_for_api_request]
    M --> O[HTMLレスポンス]
    N --> P[JSONレスポンス]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-26-01 | ローカルリクエスト判定 | ローカルリクエストのみ詳細表示 | show_detailed_exceptions未設定時 |
| BR-26-02 | X-Cascade処理 | "pass"の場合はRoutingErrorに変換 | ヘッダーが"pass"の場合 |
| BR-26-03 | 原因チェーン表示 | 例外の原因（cause）を再帰的に表示 | causeが存在する場合 |
| BR-26-04 | ソースコード抽出 | エラー発生箇所の前後数行を抽出 | ソースファイルが存在する場合 |

### 計算ロジック

ステータスコード決定：
```ruby
# ExceptionWrapper#status_code
# 例外クラスに対応するHTTPステータスコードを返す
ActionDispatch::ExceptionWrapper.rescue_responses[exception.class.name] || 500
```

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

### テーブル別操作詳細

本機能はデータベースを直接操作しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 404 | ActionController::RoutingError | ルートが見つからない | routes.rbを確認 |
| 404 | ActionController::UnknownAction | アクションが未定義 | コントローラを確認 |
| 404 | ActionView::MissingTemplate | テンプレートが見つからない | ビューファイルを確認 |
| 500 | 各種例外 | アプリケーションエラー | スタックトレースを確認 |

### リトライ仕様

リトライ機構は提供されない。エラー修正後に再リクエストが必要。

## トランザクション仕様

本機能はデータベーストランザクションを使用しない。

## パフォーマンス要件

- エラー表示は開発環境でのみ有効化推奨
- ソースコード抽出はファイルI/Oを伴うため、大量のエラー時は負荷に注意

## セキュリティ考慮事項

- 本番環境では詳細なエラー情報を表示しないこと
- show_detailed_exceptions を本番でtrueにしないこと
- スタックトレースにはセキュリティ上の機密情報が含まれる可能性がある

## 備考

- register_interceptor で例外インターセプターを追加可能
- rescue_responses でカスタム例外とステータスコードのマッピングを追加可能
- ExceptionWrapperで例外情報のラップと整形を担当

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: ミドルウェアの基本構造を理解する

DebugExceptionsミドルウェアのエントリーポイントを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | debug_exceptions.rb | `actionpack/lib/action_dispatch/middleware/debug_exceptions.rb` | callメソッド、例外キャッチ、ExceptionWrapper作成 |

**読解のコツ**: Rackミドルウェアとしての構造（initialize, call）を理解し、例外発生時の処理フローを追う。

**主要処理フロー**:
- **23-28行目**: initialize でアプリケーションとオプションを保存
- **30-47行目**: call メソッドで例外をキャッチ
- **33-36行目**: X-Cascadeヘッダー処理
- **39-46行目**: 例外キャッチとrender_exception呼び出し

#### Step 2: 例外レンダリングを理解する

エラー画面のレンダリング処理を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | debug_exceptions.rb | `actionpack/lib/action_dispatch/middleware/debug_exceptions.rb` | render_exception、render_for_browser_request、render_for_api_request |

**主要処理フロー**:
- **58-78行目**: render_exception で表示判定とレンダリング
- **80-95行目**: render_for_browser_request でHTMLレスポンス生成
- **97-119行目**: render_for_api_request でJSONレスポンス生成
- **121-135行目**: create_template でDebugViewを作成

#### Step 3: ログ出力を理解する

エラーログの出力処理を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | debug_exceptions.rb | `actionpack/lib/action_dispatch/middleware/debug_exceptions.rb` | log_error、compose_exception_message |

**主要処理フロー**:
- **141-149行目**: log_error でログ出力
- **151-181行目**: compose_exception_message でメッセージを組み立て

### プログラム呼び出し階層図

```
Rack ミドルウェアスタック
    │
    └─ ActionDispatch::DebugExceptions#call (30行目)
           │
           ├─ @app.call(env) (31行目)
           │      └─ 次のミドルウェア/アプリケーション
           │
           └─ rescue Exception (39行目)
                  │
                  ├─ ExceptionWrapper.new (42行目)
                  │
                  ├─ invoke_interceptors (44行目)
                  │      └─ @interceptors.each (51行目)
                  │
                  ├─ wrapper.show? (45行目)
                  │
                  └─ render_exception (46行目)
                         │
                         ├─ log_error (59行目)
                         │
                         └─ render_for_browser_request (73行目)
                                │
                                ├─ create_template (81行目)
                                │      └─ DebugView.new (122行目)
                                │
                                └─ template.render (91行目)
                                       └─ rescues/layout.html.erb
```

### データフロー図

```
[入力]                      [処理]                           [出力]

例外オブジェクト ───▶ ExceptionWrapper ───▶ 整形された例外情報
      │                    │
      │                    ▼
Rack env ───▶ Request 作成 ───▶ リクエスト情報
      │                    │
      │                    ▼
      │              ┌─────────────────┐
      │              │ DebugView       │
      │              │ (テンプレート)  │───▶ HTML/JSON/Text
      │              └─────────────────┘
      │                    │
      │                    ▼
      └──────────────▶ Logger ───▶ ログファイル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| debug_exceptions.rb | `actionpack/lib/action_dispatch/middleware/debug_exceptions.rb` | ソース | ミドルウェア本体 |
| exception_wrapper.rb | `actionpack/lib/action_dispatch/middleware/exception_wrapper.rb` | ソース | 例外ラッパー |
| debug_view.rb | `actionpack/lib/action_dispatch/middleware/debug_view.rb` | ソース | デバッグビュークラス |
| layout.html.erb | `actionpack/lib/action_dispatch/middleware/templates/rescues/layout.html.erb` | テンプレート | エラー表示レイアウト |
| diagnostics.html.erb | `actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb` | テンプレート | 診断情報表示 |
| routing_error.html.erb | `actionpack/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb` | テンプレート | ルーティングエラー表示 |
| missing_template.html.erb | `actionpack/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb` | テンプレート | テンプレート未検出表示 |
| unknown_action.html.erb | `actionpack/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb` | テンプレート | アクション未定義表示 |
