# 機能設計書 177-エラーメッセージ取得

## 概要

本ドキュメントは、libuv の `uv_strerror()` / `uv_strerror_r()` 関数によるエラーコードから説明文字列への変換機能について、その設計仕様を記載する。

### 本機能の処理概要

`uv_strerror()` はlibuvのエラーコードを人間が読みやすいエラー説明メッセージ文字列に変換する関数である。`uv_strerror_r()` はリエントラント版で、呼び出し元が提供するバッファに文字列を格納する。

**業務上の目的・背景**：libuvのAPI関数は失敗時に負の整数値をエラーコードとして返すが、数値だけではエラーの内容が分かりにくい。本機能はエラーコードを「permission denied」「connection refused」といった説明文字列に変換し、ログ出力やデバッグメッセージの生成、ユーザーへのエラー通知に利用する。`uv_strerror()` は静的文字列または動的割り当て文字列を返す非リエントラント版、`uv_strerror_r()` は呼び出し元バッファを使用するリエントラント版である。

**機能の利用シーン**：エラーログの出力、デバッグ時のエラー内容確認、ユーザー向けエラーメッセージの生成、テスト時のエラー内容検証、例外メッセージへのエラー情報付与などに利用される。

**主要な処理内容**：
1. エラーコードに基づく UV_ERRNO_MAP マクロによる switch 分岐
2. 既知のエラーコードの場合、対応するメッセージ文字列を返却
3. 不明なエラーコードの場合、「Unknown system error %d」形式の文字列を生成

**関連システム・外部連携**：なし（ライブラリ内部のマッピングテーブルのみ使用）。

**権限による制御**：特別な権限は不要である。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 4 | エラーコード | 主機能 | uv_strerror()/uv_strerror_r()によるエラーコードから説明文字列の取得API定義 |

## 機能種別

データ変換処理（エラーコードから説明文字列への変換）

## 入力仕様

### 入力パラメータ

#### uv_strerror()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| err | int | Yes | libuvエラーコード（負の整数） | 特に制限なし |

#### uv_strerror_r()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| err | int | Yes | libuvエラーコード（負の整数） | 特に制限なし |
| buf | char* | Yes | 結果を格納するバッファ | - |
| buflen | size_t | Yes | バッファのサイズ | - |

### 入力データソース

libuv API関数の戻り値として返されるエラーコード。

## 出力仕様

### 出力データ

#### uv_strerror()

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | const char* | エラー説明メッセージ文字列。既知エラーは静的文字列、不明エラーは動的割り当て文字列 |

#### uv_strerror_r()

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | char* | 引数で渡された buf ポインタをそのまま返す |

### 出力先

`uv_strerror()`: 戻り値として文字列ポインタを返却。
`uv_strerror_r()`: 引数 buf に文字列を格納し、buf ポインタを返却。

## 処理フロー

### 処理シーケンス

```
1. [uv_strerror] UV_ERRNO_MAP マクロによる switch 分岐
   ├─ 既知エラー: 対応するメッセージ文字列リテラルを返す
   └─ 不明エラー: uv__unknown_err_code() でヒープに文字列を生成して返す

2. [uv_strerror_r] UV_ERRNO_MAP マクロによる switch 分岐
   ├─ 既知エラー: snprintf で buf にメッセージをコピー
   └─ 不明エラー: snprintf で "Unknown system error %d" を buf に書込
   └─ buf を返す
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{err は既知のエラーコード?}
    B -->|Yes: uv_strerror| C[静的メッセージ文字列を返す]
    B -->|Yes: uv_strerror_r| D[snprintf で buf にメッセージをコピー]
    B -->|No: uv_strerror| E[uv__unknown_err_code で動的文字列生成]
    B -->|No: uv_strerror_r| F[snprintf で Unknown system error を buf に書込]
    D --> G[buf を返す]
    F --> G
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-177-01 | 既知エラーマッピング | UV_ERRNO_MAP に定義された約50種のエラーコードに対してメッセージを返す | 既知エラーコード |
| BR-177-02 | 不明エラー処理 | 不明なエラーコードは "Unknown system error %d" 形式で返す | UV_ERRNO_MAP に該当しないエラーコード |
| BR-177-03 | リエントラント版のバッファ使用 | uv_strerror_r() は呼び出し元のバッファを使用するためスレッドセーフ | uv_strerror_r() 呼出時 |

### 計算ロジック

`UV_ERRNO_MAP` マクロの展開により、`UV_STRERROR_GEN` マクロが各エラーコードに対する case 文を生成する:
```c
#define UV_STRERROR_GEN(name, msg) case UV_ ## name: return msg;
```

例: `case UV_EACCES: return "permission denied";`

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

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

該当なし。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| (なし) | - | 本関数自体はエラーを返さない | - |

### リトライ仕様

不要。

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

該当なし。

## パフォーマンス要件

switch 文による定数時間のルックアップ。極めて軽量。ただし `uv_strerror()` で不明エラーの場合はヒープ割り当てが発生する。

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

- `uv_strerror()` で不明エラーが返す文字列はヒープ割り当てされるため、メモリリークの可能性がある（libuvは解放しない）。
- `uv_strerror_r()` はバッファオーバーフローを防ぐため buflen パラメータを使用する。

## 備考

- `uv_strerror()` は不明エラーの場合にヒープ割り当てを行うため、高頻度の呼び出しにはリエントラント版 `uv_strerror_r()` の使用が推奨される。
- エラーコードとメッセージの対応は `UV_ERRNO_MAP` マクロ（include/uv.h L74-159）で一元管理されている。
- `uv__unknown_err_code()` はヒープ割り当てに失敗した場合 "Unknown system error" という静的文字列を返す。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | UV_ERRNO_MAP マクロ（74-159行目）。全エラーコードとメッセージの定義 |

**読解のコツ**: `UV_ERRNO_MAP(XX)` は X-macro パターンを使用する。`XX(name, msg)` 形式の引数を受け取り、利用側で XX を具体的なマクロに展開する。例えば `XX(EACCES, "permission denied")` は `case UV_EACCES: return "permission denied";` に展開される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | uv.h | `include/uv.h` | API宣言（425-426行目）: `uv_strerror()` と `uv_strerror_r()` |

#### Step 3: 実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | uv-common.c | `src/uv-common.c` | uv__unknown_err_code()（198-206行目）、uv_strerror_r()（231-241行目）、uv_strerror()（244-251行目） |

**主要処理フロー**:
- **198-206行目**: `uv__unknown_err_code()` - ヒープに "Unknown system error %d" を生成。メモリ不足時は静的文字列を返す
- **231-233行目**: `UV_STRERROR_GEN_R` マクロ定義。snprintf で buf にメッセージを書き込む
- **234-240行目**: `uv_strerror_r()` - switch文で既知エラーを処理、default で "Unknown system error %d" を書き込む
- **244行目**: `UV_STRERROR_GEN` マクロ定義。case 文でメッセージリテラルを return
- **245-250行目**: `uv_strerror()` - switch文で既知エラーを処理、不明エラーは `uv__unknown_err_code()` を呼び出す

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

```
uv_strerror(err) / uv_strerror_r(err, buf, buflen)
    |
    +-- [既知エラー]
    |   +-- UV_ERRNO_MAP マクロ展開によるswitch分岐
    |   +-- メッセージ文字列を返す
    |
    +-- [不明エラー]
        +-- [uv_strerror] uv__unknown_err_code(err)
        |   +-- uv__strdup(buf)  [ヒープ割り当て]
        +-- [uv_strerror_r] snprintf(buf, buflen, ...)
```

### データフロー図

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

err ──────▶ uv_strerror() ──────────────▶ const char*
(int)           |                             (エラーメッセージ文字列)
                +-- UV_ERRNO_MAP switch分岐
                +-- 既知: 静的文字列
                +-- 不明: ヒープ割当文字列

err, buf ──▶ uv_strerror_r() ─────────▶ char* buf
buflen          |                         (バッファにメッセージ格納)
                +-- UV_ERRNO_MAP switch分岐
                +-- snprintf でバッファ書込
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | API宣言、UV_ERRNO_MAP マクロ定義 |
| uv-common.c | `src/uv-common.c` | ソース | uv_strerror()、uv_strerror_r()、uv__unknown_err_code() の実装 |
