# 画面設計書 15-例外情報パネル

## 概要

本ドキュメントは、Symfony WebProfilerBundleが提供する「例外情報パネル」画面の設計書である。リクエスト処理中に発生した例外・エラーの詳細情報（スタックトレース等）をプロファイラー内で表示するコレクターパネルを定義する。

### 本画面の処理概要

**業務上の目的・背景**：アプリケーション開発中に発生する例外やエラーの原因を特定するために、例外のスタックトレース、例外クラス、メッセージ、発生箇所の詳細情報が不可欠である。本パネルは、ExceptionDataCollectorが収集した例外情報を、ErrorHandlerコンポーネントのHtmlErrorRendererを使用して詳細に表示する。プロファイラーの過去のリクエストについても例外情報を遡って確認できる。

**画面へのアクセス方法**：プロファイラーパネル画面の左サイドメニューから「Exception」を選択してアクセスする。例外が発生したリクエストのプロファイルを開いた場合、自動的にこのパネルが優先表示される（ProfilerController::panelAction 89-91行目）。

**主要な操作・処理内容**：
1. 例外のスタックトレース確認 -- 例外発生時のコールスタックを展開表示
2. 例外詳細情報の確認 -- 例外クラス、メッセージ、発生ファイル・行番号の確認
3. コードスニペット表示 -- 例外発生箇所のソースコードを行番号付きで表示

**画面遷移**：
- 遷移元：プロファイラーパネルのメニュー選択、例外発生時の自動パネル選択
- 遷移先：ソースファイル表示（ファイルリンク）、プロファイラーの他パネルへの遷移

**権限による表示制御**：開発環境でのみ利用可能。本番環境ではプロファイラー自体が無効。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 63 | WebProfilerBundle | 主機能 | ExceptionPanelControllerによる例外詳細情報の表示 |
| 13 | ErrorHandler | 主機能 | HtmlErrorRendererによる例外スタックトレースのレンダリング |
| 2 | HttpKernel | 補助機能 | ExceptionDataCollectorによる例外情報の収集 |

## 画面種別

詳細（コレクターパネル）

## URL/ルーティング

| ルート名 | URL | コントローラー |
|---------|-----|--------------|
| _profiler | `/_profiler/{token}?panel=exception` | `web_profiler.controller.profiler::panelAction` |
| _profiler_exception | `/_profiler/{token}/exception` | `web_profiler.controller.exception_panel::body` |
| _profiler_exception_css | `/_profiler/{token}/exception.css` | `web_profiler.controller.exception_panel::stylesheet` |

## 入出力項目

| 項目名 | 種別 | 型 | 説明 |
|--------|------|-----|------|
| token | 入力（URLパラメータ） | string | プロファイラートークン |
| panel | 入力（クエリパラメータ） | string | "exception"固定 |
| collector | テンプレート変数 | ExceptionDataCollector | 例外情報コレクター |

## 表示項目

### メニュー表示

| 表示項目 | データソース | 表示形式 | 説明 |
|----------|-------------|---------|------|
| Exceptionラベル | 固定文字列 | テキスト+アイコン | メニュー項目名 |
| ステータスインジケーター | collector.hasexception | CSSクラス | 例外あり=label-status-error、なし=disabled |
| 例外カウント | collector.hasexception | バッジ | 例外がある場合「1」を表示 |

### パネル表示

| 表示項目 | データソース | 表示形式 | 説明 |
|----------|-------------|---------|------|
| パネルタイトル | 固定文字列 | h2見出し | "Exceptions" |
| 例外なしメッセージ | collector.hasexception | テキスト | 例外がない場合に表示 |
| 例外詳細（body） | ExceptionPanelController::body | HTMLフラグメント | HtmlErrorRendererによるスタックトレース等 |
| 例外スタイルシート | ExceptionPanelController::stylesheet | CSSインクルード | 例外表示用スタイル |

## イベント仕様

### 1-例外詳細の表示

パネル内でESI/サブリクエストとして`ExceptionPanelController::body`が呼び出され、HtmlErrorRendererが例外の詳細HTML（スタックトレース、コードスニペット等）を生成する。`render(controller(...))`Twig関数により実現される。

### 2-スタイルシートの読み込み

headブロック内で`ExceptionPanelController::stylesheet`が呼び出され、例外表示用のCSSが動的に生成される。加えて`exception.css.twig`の内容もインクルードされる。

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| - | - | - | 本画面はデータベース操作を行わない |

## メッセージ仕様

| メッセージ種別 | メッセージ内容 | 表示条件 |
|--------------|--------------|---------|
| 情報 | "No exception was thrown and caught." | 例外がない場合 |

## 例外処理

| 例外条件 | 処理 | レスポンス |
|---------|------|----------|
| profilerがnull（ExceptionPanelController） | NotFoundHttpException発生 | 404エラー |
| プロファイルが見つからない（panelAction共通） | info画面表示 | 200（情報画面） |

## 備考

- 例外パネルのbody部分とstylesheet部分は、`render(controller(...))`によるサブリクエストで動的に生成される（exception.html.twig 6-7行目、42行目）
- HtmlErrorRendererはErrorHandlerコンポーネントに属し、開発環境用の例外詳細表示ロジックを提供する
- exception.css.twigにより追加のスタイル調整が行われる（タブナビゲーションの互換性スタイル等、28-32行目）
- 例外が存在するプロファイルを開いた場合、panelAction内で自動的にexceptionパネルが選択される（89-91行目）

---

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

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

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ExceptionPanelController.php | `src/Symfony/Bundle/WebProfilerBundle/Controller/ExceptionPanelController.php` | ExceptionDataCollectorからException情報を取得し、HtmlErrorRendererに渡す構造 |

**読解のコツ**: このコントローラーはProfilerControllerとは別の独立したコントローラーで、例外パネル専用。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | exception.html.twig | `src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.html.twig` | layout.html.twigを継承。`head`ブロックでCSS読み込み、`panel`ブロックでbody表示 |
| 2-2 | ProfilerController.php | `src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php` | panelAction（65-117行目）で例外がある場合にパネルが自動選択される（89-91行目） |

**主要処理フロー**:
1. **panelAction 89-91行目**: ExceptionDataCollectorに例外がある場合、panelを'exception'に自動設定
2. **exception.html.twig 6行目**: `render(controller('web_profiler.controller.exception_panel::stylesheet'))`でCSS取得
3. **exception.html.twig 42行目**: `render(controller('web_profiler.controller.exception_panel::body'))`で例外詳細HTML取得

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ExceptionPanelController.php | `src/Symfony/Bundle/WebProfilerBundle/Controller/ExceptionPanelController.php` | `body()`メソッド（37-49行目）: プロファイルからExceptionを取得し、HtmlErrorRenderer::getBody()で詳細HTML生成 |
| 3-2 | ExceptionPanelController.php | 同上 | `stylesheet()`メソッド（54-57行目）: HtmlErrorRenderer::getStylesheet()でCSS生成 |

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

```
GET /_profiler/{token}?panel=exception
    |
    +-- ProfilerController::panelAction()  [65行目]
            |
            +-- Profiler::loadProfile()
            +-- ExceptionDataCollector::hasException() で自動パネル選択  [89行目]
            +-- Twig::render(exception.html.twig)
                    |
                    +-- extends layout.html.twig
                    |
                    +-- render(controller('...exception_panel::stylesheet'))
                    |       +-- ExceptionPanelController::stylesheet()  [54行目]
                    |               +-- HtmlErrorRenderer::getStylesheet()
                    |
                    +-- render(controller('...exception_panel::body'))
                            +-- ExceptionPanelController::body()  [37行目]
                                    +-- Profiler::loadProfile()
                                    +-- ExceptionDataCollector::getException()
                                    +-- HtmlErrorRenderer::getBody()
```

### データフロー図

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

token (URL)          ProfilerController              exception.html.twig
panel=exception --> ::panelAction()             -->  (例外詳細パネル)
                          |
                     Profile::getCollector('exception')
                          |
                     ExceptionDataCollector
                          |
                     ExceptionPanelController::body()
                          |
                     HtmlErrorRenderer::getBody()
                          |
                     スタックトレースHTML
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ExceptionPanelController.php | `src/Symfony/Bundle/WebProfilerBundle/Controller/ExceptionPanelController.php` | ソース | 例外パネルのbodyとstylesheetを生成 |
| ProfilerController.php | `src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php` | ソース | panelActionでパネル表示制御 |
| exception.html.twig | `src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.html.twig` | テンプレート | 例外パネルのHTML |
| exception.css.twig | `src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.css.twig` | テンプレート | 例外パネルの追加CSS |
| layout.html.twig | `src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig` | テンプレート | パネル共通レイアウト |
| profiler.php | `src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/profiler.php` | 設定 | ルーティング定義（_profiler_exception, _profiler_exception_css） |
