# 通知設計書 7-OS\ErrnoException

## 概要

本ドキュメントは、HH\Lib\OS\ErrnoException クラスによる C言語の errno 変数で報告されるエラーの例外通知機能について記載する。

### 本通知の処理概要

OS\ErrnoException は、POSIX/Unix システムコールが失敗した際に C言語の errno グローバル変数に設定されるエラーコードを Hack の例外として表現する基底クラスである。この例外クラスにより、低レベルの OS エラーを型安全に通知し、適切なエラーハンドリングを可能にする。

**業務上の目的・背景**：Hack/HHVM でファイル操作やネットワーク通信などの OS レベルの操作を行う際、様々なエラーが発生する可能性がある。従来の errno ベースのエラーチェックは見落としやすく、エラーの種類に応じた適切な処理が困難であった。ErrnoException とそのサブクラス群を使用することで、型システムを活用した堅牢なエラーハンドリングが実現できる。

**通知の送信タイミング**：OS レベルの操作（ファイル操作、ソケット操作、プロセス操作など）が失敗した際に、対応する Errno 値とともにスローされる。HSL の OS モジュールの各関数から、適切なタイミングでスローされる。

**通知の受信者**：OS 操作を呼び出したコード（try-catch ブロックを使用するアプリケーションコード）が受信者となる。

**通知内容の概要**：Errno 値（エラーコード）とエラーメッセージが含まれる。getErrno() メソッドでエラーコードを取得可能。

**期待されるアクション**：受信者は例外の種類に応じて適切なエラーハンドリングを行う。可能であれば具体的なサブクラス（NotFoundException、PermissionException など）でキャッチすることが推奨される。

## 通知種別

例外通知（OSエラー・errno ベース）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（例外スロー） |
| 優先度 | N/A（例外通知のため） |
| リトライ | なし（呼び出し側で制御） |

### 送信先決定ロジック

例外は呼び出しスタックを遡って伝播し、最初の適切な catch ブロックで捕捉される。

## 通知テンプレート

### 例外の場合

| 項目 | 内容 |
|-----|------|
| 例外クラス | HH\Lib\OS\ErrnoException |
| 親クラス | \Exception |
| 名前空間 | HH\Lib\OS |

### 例外データ構造

```hack
class ErrnoException extends \Exception {
  private Errno $errno;

  public function __construct(Errno $errno, string $message);
  public function getErrno(): Errno;
}
```

### 主要サブクラス

| サブクラス | 対応 Errno | 説明 |
|----------|-----------|------|
| ChildProcessException | ECHILD | 子プロセス関連エラー |
| ConnectionException | （抽象） | 接続関連エラーの基底 |
| BrokenPipeException | EPIPE, ESHUTDOWN | パイプ破損エラー |
| ConnectionAbortedException | ECONNABORTED | 接続中断エラー |
| ConnectionRefusedException | ECONNREFUSED | 接続拒否エラー |
| ConnectionResetException | ECONNRESET | 接続リセットエラー |
| AlreadyExistsException | EEXIST | リソース既存エラー |
| NotFoundException | ENOENT | リソース未検出エラー |
| IsADirectoryException | EISDIR | ディレクトリ操作エラー |
| IsNotADirectoryException | ENOTDIR | 非ディレクトリ操作エラー |
| PermissionException | EACCES, EPERM | 権限エラー |
| ProcessLookupException | ESRCH | プロセス検索エラー |
| TimeoutException | ETIMEDOUT | タイムアウトエラー |
| BlockingIOException | EAGAIN, EALREADY, EINPROGRESS | ブロッキングI/Oエラー |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| $errno | Errno 列挙値 | OS からのエラーコード | Yes |
| $message | エラーメッセージ | エラー説明文字列 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| システムコール失敗 | ファイル操作失敗 | errno が設定された場合 | open, read, write など |
| システムコール失敗 | ネットワーク操作失敗 | errno が設定された場合 | connect, bind, listen など |
| システムコール失敗 | プロセス操作失敗 | errno が設定された場合 | fork, exec, wait など |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| なし | errno が設定された場合は必ずスローされる |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[OS 操作実行] --> B{操作成功?}
    B -->|Yes| C[正常終了]
    B -->|No| D[errno 取得]
    D --> E{適切なサブクラスあり?}
    E -->|Yes| F[サブクラスをスロー]
    E -->|No| G[ErrnoException をスロー]
    F --> H[呼び出し元の catch へ]
    G --> H
    H --> I[エラーハンドリング]
```

## データベース参照・更新仕様

該当なし（OS レベルの例外通知のため）

### 参照テーブル一覧

該当なし

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 権限エラー | EACCES, EPERM | 権限を確認し、適切な権限で再実行 |
| 未検出エラー | ENOENT | ファイル/パスの存在を確認 |
| 既存エラー | EEXIST | 既存リソースの処理方法を決定 |
| 接続エラー | ECONNREFUSED, ECONNRESET | 接続先の状態を確認、リトライ |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 呼び出し側で制御 |
| リトライ間隔 | 呼び出し側で制御 |
| リトライ対象エラー | BlockingIOException（EAGAIN等）は一般的にリトライ可能 |

## 配信設定

### レート制限

該当なし（例外通知のため）

### 配信時間帯

制限なし

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

- エラーメッセージにファイルパスやシステム情報が含まれる可能性があるため、ユーザーへの表示時は適切にサニタイズする
- 詳細なエラー情報は攻撃者に有用な情報を与える可能性があるため、本番環境ではログに記録し、ユーザーには一般的なエラーメッセージを表示することを推奨

## 備考

- サブクラスでの catch を推奨（コードコメントに ANTIPATTERN と RECOMMENDED の例示あり）
- getCode() メソッドは非推奨で getErrno() の使用が推奨される
- Errno 列挙型は OS によって値が異なる場合がある（MacOS と Linux の違い）

---

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

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

### 推奨読解順序

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

Errno 列挙型と ErrnoException クラスの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Errno.php | `src/os/Errno.php` | Errno 列挙型の定義（37-200行目） |
| 1-2 | ErrnoException.php | `src/os/ErrnoException.php` | 例外クラスの構造（52-76行目） |

**読解のコツ**: Errno 列挙型は OS 間の移植性を考慮しており、負の値は未定義の定数を表す。

#### Step 2: 基底クラスを理解する

ErrnoException クラスの実装を詳細に理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ErrnoException.php | `src/os/ErrnoException.php` | コンストラクタ（53-58行目） |
| 2-2 | ErrnoException.php | `src/os/ErrnoException.php` | getErrno メソッド（60-62行目） |
| 2-3 | ErrnoException.php | `src/os/ErrnoException.php` | getCode メソッド（非推奨）（72-75行目） |

**主要処理フロー**:
1. **行53-58**: コンストラクタで Errno と message を受け取り、親クラスと $code を設定
2. **行60-62**: getErrno で Errno 値を取得
3. **行64-75**: getCode は非推奨（Deprecated）として定義

#### Step 3: サブクラス群を理解する

各種具象例外クラスの実装パターンを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ErrnoException.php | `src/os/ErrnoException.php` | BlockingIOException（78-96行目） |
| 3-2 | ErrnoException.php | `src/os/ErrnoException.php` | ChildProcessException（98-106行目） |
| 3-3 | ErrnoException.php | `src/os/ErrnoException.php` | ConnectionException 系（108-155行目） |
| 3-4 | ErrnoException.php | `src/os/ErrnoException.php` | その他の例外（157-234行目） |

**主要処理フロー**:
- 単一 Errno の例外: _getValidErrno() メソッドで対応する Errno を返す
- 複数 Errno の例外: _getValidErrnos() メソッドで keyset を返し、invariant でチェック

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

```
OS 操作（ファイル/ネットワーク/プロセス）
    |
    +-- [エラー発生]
            |
            +-- errno 値を取得
            |
            +-- 適切な Exception サブクラスを選択
            |       |
            |       +-- ENOENT -> NotFoundException
            |       +-- EACCES/EPERM -> PermissionException
            |       +-- ECONNREFUSED -> ConnectionRefusedException
            |       +-- その他 -> ErrnoException
            |
            +-- throw $exception
                    |
                    +-- 呼び出し元の catch ブロック
```

### データフロー図

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

OS システムコール
    |
    v
[エラー発生]
    |
    v
errno (int) ─────▶ Errno 列挙型に変換 ─────▶ Exception サブクラス
                          │                         │
                          v                         v
                   メッセージ生成            throw Exception
                          │                         │
                          v                         v
                   ErrnoException              try-catch
                   のコンストラクタ           でハンドリング
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ErrnoException.php | `src/os/ErrnoException.php` | ソース | ErrnoException とサブクラスの実装 |
| Errno.php | `src/os/Errno.php` | ソース | Errno 列挙型の定義 |
