# 機能設計書 178-エラー名取得

## 概要

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

### 本機能の処理概要

`uv_err_name()` はlibuvのエラーコードをエラー名文字列（例: "EACCES", "ECONNREFUSED"）に変換する関数である。`uv_err_name_r()` はリエントラント版で、呼び出し元が提供するバッファに文字列を格納する。

**業務上の目的・背景**：エラーの種類を識別するために、数値のエラーコードではなく文字列名（"EACCES" 等）が必要な場面がある。本機能はエラーコードをPOSIX風のエラー名に変換する。`uv_strerror()` が「permission denied」のような説明メッセージを返すのに対し、本関数は「EACCES」のようなシンボル名を返す。ログ出力でエラーを一意に識別したり、エラー名による条件分岐を行う場合に有用である。

**機能の利用シーン**：構造化ログでのエラー種別出力、エラーコードのシリアライズ、テスト時のエラー種別検証、デバッグ出力でのエラー識別、エラーレポートの生成などに利用される。

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

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

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

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

#### uv_err_name()

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

#### uv_err_name_r()

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

### 入力データソース

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

## 出力仕様

### 出力データ

#### uv_err_name()

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | const char* | エラー名文字列（例: "EACCES"）。既知エラーは静的文字列、不明エラーは動的割り当て文字列 |

#### uv_err_name_r()

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

### 出力先

`uv_err_name()`: 戻り値として文字列ポインタを返却。
`uv_err_name_r()`: 引数 buf にエラー名を格納し、buf ポインタを返却。

## 処理フロー

### 処理シーケンス

```
1. [uv_err_name] UV_ERRNO_MAP マクロによる switch 分岐
   ├─ 既知エラー: エラー名文字列リテラル（"EACCES"等）を返す
   └─ 不明エラー: uv__unknown_err_code() で文字列を生成して返す

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

### フローチャート

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

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-178-01 | 既知エラーマッピング | UV_ERRNO_MAP に定義された約50種のエラーコードに対してエラー名を返す | 既知エラーコード |
| BR-178-02 | 不明エラー処理 | 不明なエラーコードは "Unknown system error %d" 形式で返す | UV_ERRNO_MAP に該当しないエラーコード |
| BR-178-03 | エラー名の形式 | エラー名は大文字のPOSIX風シンボル名（"EACCES", "ECONNREFUSED" 等） | 既知エラーコード |

### 計算ロジック

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

例: `case UV_EACCES: return "EACCES";`

`uv_err_name_r()` では `UV_ERR_NAME_GEN_R` マクロが `uv__strscpy()` によるバッファコピーを生成する:
```c
#define UV_ERR_NAME_GEN_R(name, _) case UV_## name: uv__strscpy(buf, #name, buflen); break;
```

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

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

該当なし。

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

該当なし。

## エラー処理

### エラーケース一覧

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

### リトライ仕様

不要。

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

該当なし。

## パフォーマンス要件

switch 文による定数時間のルックアップ。極めて軽量。

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

`uv_err_name()` で不明エラーの場合はヒープ割り当てが発生する（`uv__unknown_err_code()` 経由）。

## 備考

- `uv_err_name_r()` は `uv__strscpy()` を使用してバッファにコピーするため、バッファオーバーフローに安全である。
- `uv_strerror()` がメッセージ（"permission denied"）を返すのに対し、本関数はエラー名（"EACCES"）を返す点が異なる。
- 両関数は同じ `UV_ERRNO_MAP` マクロを使用するが、展開マクロが異なる（`UV_ERR_NAME_GEN` vs `UV_STRERROR_GEN`）。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | UV_ERRNO_MAP マクロ（74-159行目）。全エラーコードの定義。XX(name, msg) 形式で name がエラー名に使用される |

**読解のコツ**: `UV_ERR_NAME_GEN(name, _)` の第2引数 `_` はエラーメッセージだが、エラー名取得では使用しない（アンダースコアで無視）。C プリプロセッサの `#name` で文字列化される。

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

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | uv-common.c | `src/uv-common.c` | uv_err_name_r()（208-218行目）、uv_err_name()（221-228行目） |

**主要処理フロー**:
- **208-210行目**: `UV_ERR_NAME_GEN_R` マクロ定義。uv__strscpy で buf にエラー名をコピー
- **211-217行目**: `uv_err_name_r()` - switch文で既知エラーを処理、default で "Unknown system error %d" を snprintf
- **221行目**: `UV_ERR_NAME_GEN` マクロ定義。case 文でエラー名リテラルを return
- **222-227行目**: `uv_err_name()` - switch文で既知エラーを処理、不明エラーは `uv__unknown_err_code()` を呼び出す

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

```
uv_err_name(err) / uv_err_name_r(err, buf, buflen)
    |
    +-- [既知エラー]
    |   +-- UV_ERRNO_MAP マクロ展開によるswitch分岐
    |   +-- エラー名文字列を返す / バッファにコピー
    |
    +-- [不明エラー]
        +-- [uv_err_name] uv__unknown_err_code(err)
        +-- [uv_err_name_r] snprintf(buf, buflen, "Unknown system error %d", err)
```

### データフロー図

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

err ──────▶ uv_err_name() ──────────▶ const char*
(int)           |                         ("EACCES" 等)
                +-- UV_ERRNO_MAP switch

err, buf ──▶ uv_err_name_r() ─────▶ char* buf
buflen          |                      ("EACCES" 等をbufに格納)
                +-- UV_ERRNO_MAP switch
                +-- uv__strscpy / snprintf
```

### 関連ファイル一覧

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