# 機能設計書 12-request_error

## 概要

本ドキュメントは、Hack Standard Library（HSL）のIO名前空間における`request_error`関数の機能設計を記述する。この関数は、現在のリクエストに対するエラー出力ハンドルを取得するための機能を提供する。

### 本機能の処理概要

`request_error`関数は、現在の実行コンテキストにおけるエラー出力ハンドルを返す。CLIモードでは標準エラー出力（STDERR）へのハンドルを提供し、HTTPリクエストモードなどではnullを返す。

**業務上の目的・背景**：アプリケーションは通常出力とエラー出力を分離する必要がある。エラーメッセージ、警告、デバッグ情報を通常の出力ストリームとは別のストリームに送ることで、ログの管理やエラーの追跡が容易になる。この関数により、実行環境に応じたエラー出力の可否を判定し、適切に処理できる。

**機能の利用シーン**：CLIツールでのエラーメッセージ出力、デバッグ情報のSTDERRへの書き込み、ログ出力の分離、パイプライン処理時のエラー分離など、エラー情報を標準出力と分けて出力したい場面で使用される。

**主要な処理内容**：
1. request_errorx()を呼び出してエラー出力ハンドルの取得を試みる
2. 取得成功時はCloseableWriteFDHandleを返す
3. EBADF（Bad File Descriptor）エラー時はnullを返す（HTTPモード等）
4. その他のエラーは例外として再スローする

**関連システム・外部連携**：OSレベルのファイルディスクリプタ操作に依存する。CLIモードではプロセスの標準エラー出力ストリームと連携する。

**権限による制御**：特段の権限制御はないが、ファイルディスクリプタへのアクセス権限はOSレベルで管理される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | 画面なし | - | 本プロジェクトはUIを持たないライブラリのため画面機能マッピングは該当しない |

## 機能種別

データ出力 / ハンドル取得

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | この関数は引数を取らない | - |

### 入力データソース

実行コンテキスト（OSのstderrファイルディスクリプタ）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | ?CloseableWriteFDHandle | エラー出力可能なI/Oハンドル。CLIモードではStdioWriteHandle、HTTPモードなどではnull |

### 出力先

呼び出し元に`CloseableWriteFDHandle`インターフェースを実装したオブジェクト、またはnullを返す

## 処理フロー

### 処理シーケンス

```
1. request_errorx()を呼び出し
   └─ エラー出力ハンドルの取得を試みる
2. 成功した場合
   └─ CloseableWriteFDHandleを返す
3. ErrnoException発生時
   ├─ EBADFエラーの場合
   │      └─ nullを返す
   └─ その他のエラーの場合
          └─ 例外を再スローする
```

### フローチャート

```mermaid
flowchart TD
    A[request_error呼び出し] --> B[request_errorx呼び出し]
    B --> C{成功?}
    C -->|Yes| D[CloseableWriteFDHandle返却]
    C -->|No| E{EBADFエラー?}
    E -->|Yes| F[null返却]
    E -->|No| G[例外再スロー]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | null許容戻り値 | HTTPモード等でエラー出力が利用できない場合はnullを返す | stderrが利用不可能な場合 |
| BR-02 | 例外抑制版 | EBADFエラーは例外をスローせずnullで返す | EBADFエラー発生時 |

### 計算ロジック

特になし

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

該当なし（本機能はI/O操作のみでデータベースを使用しない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| EBADF | OS\ErrnoException | stderrが利用不可能な場合（HTTPモード等） | 内部で捕捉しnullを返す |
| その他 | OS\ErrnoException | ファイルディスクリプタ操作の失敗 | 例外として再スローされる |

### リトライ仕様

リトライは実装されていない

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

該当なし

## パフォーマンス要件

特段のパフォーマンス要件なし。request_output()と異なりメモ化されていないため、呼び出しごとにハンドル取得処理が実行される。

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

- エラー出力ハンドルへの書き込み内容は呼び出し側の責任で管理する
- 機密情報のエラー出力には注意が必要

## 備考

- 例外をスローする版として`request_errorx()`が提供されている
- request_error()はrequest_errorx()のラッパーとして実装されている
- 関連関数として`request_output()`（標準出力）、`request_input()`（入力ハンドル）がある

---

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

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

### 推奨読解順序

#### Step 1: インターフェース定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Handle.php | `src/io/Handle.php` | IOハンドルの基本インターフェース |
| 1-2 | WriteHandle.php | `src/io/WriteHandle.php` | 書き込みハンドルのインターフェース定義 |
| 1-3 | intersection_interfaces.php | `src/io/intersection_interfaces.php` | CloseableWriteFDHandleインターフェースの定義（102-103行目） |

**読解のコツ**: CloseableWriteFDHandleは複合インターフェースで、WriteFDHandle、CloseableFDHandle、CloseableWriteHandleを継承している。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | stdio.php | `src/io/stdio.php` | request_error関数およびrequest_errorx関数の本体 |

**主要処理フロー**:
1. **46-55行目**: request_error関数本体。try-catchでrequest_errorx()を呼び出し
2. **47-48行目**: request_errorx()の戻り値をそのまま返す
3. **49-54行目**: EBADFエラー時にnullを返す
4. **66-68行目**: request_errorx関数。StdioWriteHandleを直接生成して返す

#### Step 3: 内部実装クラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | StdioWriteHandle.php | `src/io/_Private/StdioWriteHandle.php` | CLI用エラー出力ハンドル実装 |
| 3-2 | FileDescriptorHandle.php | `src/io/_Private/FileDescriptorHandle.php` | ファイルディスクリプタハンドルの基底クラス |

**主要処理フロー**:
- **StdioWriteHandle**: FileDescriptorHandleを継承し、OS\stderr()からのファイルディスクリプタを使用

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

```
IO\request_error()
    │
    └─ IO\request_errorx()
           │
           ├─ OS\stderr()
           │      └─ ファイルディスクリプタ取得
           │
           └─ _IO\StdioWriteHandle
                  ├─ FileDescriptorHandle
                  │      └─ OS\fcntl() - O_NONBLOCK設定
                  └─ FileDescriptorWriteHandleTrait
```

### データフロー図

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

なし ─────────────▶ request_error() ──────────▶ ?CloseableWriteFDHandle
                          │
                    ┌─────┴─────┐
                    ▼           ▼
              CLIモード    HTTPモード
                    │           │
                    ▼           ▼
            StdioWriteHandle   null
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| stdio.php | `src/io/stdio.php` | ソース | request_error、request_errorx関数のエントリーポイント |
| Handle.php | `src/io/Handle.php` | ソース | 基底インターフェース定義 |
| WriteHandle.php | `src/io/WriteHandle.php` | ソース | 書き込みハンドルインターフェース |
| StdioWriteHandle.php | `src/io/_Private/StdioWriteHandle.php` | ソース | CLI用出力ハンドル実装 |
| FileDescriptorHandle.php | `src/io/_Private/FileDescriptorHandle.php` | ソース | FDハンドル基底クラス |
| intersection_interfaces.php | `src/io/intersection_interfaces.php` | ソース | CloseableWriteFDHandle定義 |
