# 帳票設計書 25-CLIエラー出力

## 概要

本ドキュメントは、Symfony ErrorHandlerコンポーネントにおける `CliErrorRenderer` クラスの帳票設計書である。例外・エラー情報をCLI向けテキスト形式で出力する機能について、出力仕様・処理フロー・データ構造を定義する。

### 本帳票の処理概要

`CliErrorRenderer` は、PHP例外（Throwable）をCLI向けのテキスト形式に変換するクラスである。`ErrorRendererInterface` を実装し、VarDumperコンポーネントの `VarCloner` と `CliDumper` を内部で使用して、例外オブジェクトをANSIカラー付きの詳細なテキスト表現として出力する。

**業務上の目的・背景**：CLIで実行されるSymfonyコマンドやバッチ処理においてエラーが発生した場合、ターミナル上で例外情報を効果的に表示する必要がある。CliErrorRendererは、VarDumperのCliDumperを活用し、例外オブジェクトの全プロパティ（メッセージ、コード、ファイル、行、スタックトレース等）をANSIカラー付きで表示する。

**帳票の利用シーン**：CLIコマンド実行中に未捕捉例外が発生した場合、ErrorHandlerのCLIモードで例外レンダリングが行われる際に使用される。

**主要な出力内容**：
1. 例外オブジェクトの全プロパティのダンプ表示
2. 例外クラス名とメッセージ
3. スタックトレース
4. ANSIカラーコードによる色分け表示

**帳票の出力タイミング**：CLIモードで未捕捉例外が発生し、ErrorHandlerが例外をレンダリングする際に出力される。

**帳票の利用者**：バックエンド開発者、DevOpsエンジニア

## 帳票種別

エラー情報ダンプ（CLIテキスト出力）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | CLIコマンド | N/A（ターミナル） | 例外発生時の自動出力 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | テキスト（ANSIカラーコード付き） |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | N/A（標準出力） |
| 出力方法 | FlattenExceptionの文字列プロパティとして保持 |
| 文字コード | UTF-8 |

### PDF固有設定

該当なし

### Excel固有設定

該当なし

## 帳票レイアウト

### レイアウト概要

VarDumperのCliDumperによる例外オブジェクトのダンプ出力。例外の全プロパティが階層的に表示される。

```
┌─────────────────────────────────────┐
│  ExceptionClass {#refId              │
│    #message: "Error message"         │
│    #code: 0                          │
│    #file: "/path/to/file.php"        │
│    #line: 42                         │
│    -trace: {                         │
│      ...スタックトレース詳細...         │
│    }                                 │
│  }                                   │
└─────────────────────────────────────┘
```

### ヘッダー部

該当なし（CliDumperのダンプ出力形式に準拠）

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | 例外クラス名 | 例外のFQCN | `Throwable` オブジェクト | `note` スタイル | 可変 |
| 2 | message | 例外メッセージ | `$exception->getMessage()` | `str` スタイル | 可変 |
| 3 | code | 例外コード | `$exception->getCode()` | `num` スタイル | 可変 |
| 4 | file | 例外発生ファイル | `$exception->getFile()` | `str` スタイル | 可変 |
| 5 | line | 例外発生行番号 | `$exception->getLine()` | `num` スタイル | 可変 |
| 6 | trace | スタックトレース | `$exception->getTrace()` | 配列ダンプ | 可変 |
| 7 | previous | 前の例外 | `$exception->getPrevious()` | 再帰ダンプ | 可変 |

### フッター部

該当なし

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| Throwable | レンダリング対象の例外 | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | プロパティ定義順 | クラス定義順 |

### 改ページ条件

該当なし

## データベース参照仕様

### 参照テーブル一覧

該当なし

### テーブル別参照項目詳細

該当なし

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| カラーサポート | `supportsColors()` をphp://stdout基準で判定 | なし | 匿名クラスでoutputStreamをstdoutに差し替え |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[render Throwable] --> B[VarCloner生成]
    B --> C[匿名CliDumperクラス生成]
    C --> D[cloneVar: 例外をクローン]
    D --> E[dump: クローンをテキスト出力]
    E --> F[FlattenException生成]
    F --> G[setAsString: ダンプ結果を設定]
    G --> H[FlattenException返却]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| メモリ不足 | 非常に深いネストの例外チェーン | PHP Fatal Error | メモリ制限の引き上げ |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 1例外（前例外チェーン含む） |
| 目標出力時間 | 50ms以内 |
| 同時出力数上限 | 1 |

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

- CLI出力のため、XSSリスクはない
- 例外のスタックトレースにはファイルパス・関数引数等の情報が含まれる
- 本番環境ではエラー出力の詳細度を適切に管理すること

## 備考

- 非常にコンパクトなクラス（47行）であり、VarClonerとCliDumperに処理を委譲
- 匿名クラスでCliDumperの`supportsColors()`をオーバーライドし、php://stdoutのカラーサポートを正しく検出
- `class_exists(CliDumper::class)` による`opcache.preload`最適化ヒントが含まれる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | FlattenException.php | `src/Symfony/Component/ErrorHandler/Exception/FlattenException.php` | 出力先データ構造。setAsString()で文字列表現を保持 |
| 1-2 | ErrorRendererInterface.php | `src/Symfony/Component/ErrorHandler/ErrorRenderer/ErrorRendererInterface.php` | render()の契約 |

**読解のコツ**: CliErrorRendererは`render()`で例外を受け取り、FlattenExceptionにダンプ文字列を設定して返す。非常にシンプルな構造。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CliErrorRenderer.php | `src/Symfony/Component/ErrorHandler/ErrorRenderer/CliErrorRenderer.php` | render()メソッド（26-45行目）が唯一の処理 |

**主要処理フロー**:
1. **28行目**: `new VarCloner()` - 例外オブジェクトのクローン用
2. **29-41行目**: 匿名CliDumperクラス生成 - `supportsColors()` をphp://stdout基準でオーバーライド
3. **43行目**: `FlattenException::createFromThrowable()` - 例外をフラット化
4. **44行目**: `$dumper->dump($cloner->cloneVar($exception), true)` - 例外をクローンしてテキストダンプ

#### Step 3: 依存クラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | VarCloner.php | `src/Symfony/Component/VarDumper/Cloner/VarCloner.php` | cloneVar()でPHP変数をDataオブジェクトに変換 |
| 3-2 | CliDumper.php | `src/Symfony/Component/VarDumper/Dumper/CliDumper.php` | dump()でDataをテキスト出力 |

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

```
CliErrorRenderer::render(Throwable)
    |
    +-- new VarCloner()
    +-- new class extends CliDumper { supportsColors() override }
    |
    +-- VarCloner::cloneVar(Throwable) -----> Data
    |
    +-- CliDumper::dump(Data, true) -----> string (ダンプ結果)
    |
    +-- FlattenException::createFromThrowable(Throwable)
    |
    +-- FlattenException::setAsString(string)
    |
    +-- return FlattenException
```

### データフロー図

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

Throwable -----> VarCloner::cloneVar() -----> Data
                                                |
                                                v
Data ----------> CliDumper::dump(Data, true) -> ANSI colored string
                                                |
                                                v
Throwable -----> FlattenException::createFromThrowable()
                        |
                        +-- setAsString(string)
                        |
                        v
                 FlattenException (with dump string)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CliErrorRenderer.php | `src/Symfony/Component/ErrorHandler/ErrorRenderer/CliErrorRenderer.php` | ソース | メインクラス（47行） |
| ErrorRendererInterface.php | `src/Symfony/Component/ErrorHandler/ErrorRenderer/ErrorRendererInterface.php` | ソース | インターフェース |
| FlattenException.php | `src/Symfony/Component/ErrorHandler/Exception/FlattenException.php` | ソース | フラット化例外 |
| VarCloner.php | `src/Symfony/Component/VarDumper/Cloner/VarCloner.php` | ソース | 変数クローナー |
| CliDumper.php | `src/Symfony/Component/VarDumper/Dumper/CliDumper.php` | ソース | CLIダンパー |
