# 通知設計書 4-push_error

## 概要

本ドキュメントは、Godotエンジンの@GlobalScope関数であるpush_error()の設計仕様を記述する。

### 本通知の処理概要

push_error()は、GDScriptや他のスクリプト言語からデバッガおよびターミナル（標準エラー出力）にエラーメッセージをプッシュするためのグローバル関数である。スタックトレース情報を含むエラー出力を生成し、開発者がランタイムエラーの発生箇所を特定できるようにする。

**業務上の目的・背景**：ゲーム開発中にスクリプトから明示的にエラー状態を報告する必要がある場面が多い。例えば、無効な引数の検出、想定外の状態遷移、リソース不足などの状況で開発者が意図的にエラーメッセージを出力し、デバッグを支援する。push_error()はassertとは異なり、実行を停止せずにエラーを記録するため、問題を報告しつつプログラムの継続実行が可能である。

**通知の送信タイミング**：スクリプトコード内でpush_error()関数が明示的に呼び出されたとき。引数として1つ以上のVariant値を受け取り、それらを連結してエラーメッセージとして出力する。

**通知の受信者**：デバッガ（エディタデバッガまたはリモートデバッガ）、ターミナル/コンソール（標準エラー出力）、ログファイル（設定されている場合）。エディタ実行中はデバッガパネルに、スタンドアロン実行時はターミナルにメッセージが表示される。

**通知内容の概要**：連結されたエラーメッセージ文字列、呼び出し元の関数名、ファイルパス、行番号、スクリプトバックトレース情報が含まれる。

**期待されるアクション**：開発者はエラーメッセージとスタックトレースを確認し、問題の原因を特定して修正する。エディタで実行中の場合はデバッガパネルでエラー行をクリックしてソースコードにジャンプできる。

## 通知種別

デバッグ/ログ通知（標準エラー出力、デバッガ通知、ログファイル出力）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 高（エラーレベル） |
| リトライ | 無 |

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

- OS::print_error()経由でLoggerにエラーメッセージが送信される
- 登録されているすべてのErrorHandlerList（エラーハンドラチェーン）に通知される
- CompositeLoggerを通じて複数の出力先（stdout、ログファイル）に同時出力される

## 通知テンプレート

### コンソール/ログ出力の場合

| 項目 | 内容 |
|-----|------|
| プレフィックス | ERROR: |
| 位置情報形式 | at: {function} ({file}:{line}) |
| バックトレース | スクリプト呼び出しスタック |

### 本文テンプレート

```
ERROR: {message}
   at: {function} ({file}:{line})
{script_backtrace}
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| message | エラーメッセージ（引数を連結） | push_error引数 | Yes |
| function | 呼び出し元関数名 | __FUNCTION__マクロ | Yes |
| file | 呼び出し元ファイルパス | __FILE__マクロ | Yes |
| line | 呼び出し元行番号 | __LINE__マクロ | Yes |
| script_backtrace | スクリプトバックトレース | ScriptServer::capture_script_backtraces | No |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| API呼び出し | push_error(args...) | 常時 | GDScriptからの直接呼び出し |
| C++マクロ | ERR_PRINT(message) | 常時 | C++コードからのエラー出力 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| CoreGlobals::print_error_enabled == false | エラー出力がグローバルで無効化されている場合 |
| is_printing_error == true | 再帰呼び出し防止 |
| _stderr_enabled == false | OS標準エラー出力が無効 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[push_error呼び出し] --> B[引数をStringに連結]
    B --> C[ERR_PRINTマクロ呼び出し]
    C --> D[_err_print_error関数]
    D --> E{is_printing_error?}
    E -->|Yes| F[フォールバック出力]
    E -->|No| G[is_printing_error = true]
    G --> H{OS初期化済み?}
    H -->|Yes| I[OS::print_error呼び出し]
    H -->|No| J[stderr直接出力]
    I --> K[Logger::log_error]
    K --> L[スクリプトバックトレース取得]
    L --> M[フォーマット出力]
    M --> N[ErrorHandlerList通知]
    N --> O[is_printing_error = false]
    O --> P[終了]
    F --> P
    J --> P
```

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

### 参照テーブル一覧

該当なし（データベースは使用しない）

### 更新テーブル一覧

該当なし（データベースは使用しない）

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 引数不足 | p_arg_count < 1 | CallError::CALL_ERROR_TOO_FEW_ARGUMENTSを設定 |
| 再帰呼び出し | is_printing_errorがtrue | フォールバック出力に切り替え |
| OS未初期化 | OS::get_singleton()がnull | stderr直接出力 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| レート制限 | なし |
| バッファリング | なし（即時出力） |

### 配信時間帯

制限なし（常時）

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

- エラーメッセージはそのまま出力されるため、機密情報を含めないよう注意が必要
- ファイルパスがフルパスで出力される場合があり、システム構成の露出に注意
- 本番環境ではログ出力を制限することを推奨

## 備考

- push_error()は可変長引数を受け取り、すべてをString変換して連結する
- ERR_PRINTマクロは内部的に同じ処理を実行する
- エラー出力後も実行は継続される（assertとは異なる）
- GDScriptではprint_stackを使用することでより詳細なスタックトレースを取得可能

---

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

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

### 推奨読解順序

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

push_errorの引数処理と内部データ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | variant_utility.h | `core/variant/variant_utility.h` | push_error関数シグネチャ（140行目） |
| 1-2 | error_macros.h | `core/error/error_macros.h` | ERR_PRINTマクロ定義（671-672行目） |

**読解のコツ**: push_errorは可変長引数（Variant**とarg_count）を受け取る。引数は内部でjoin_string関数で連結される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | variant_utility.cpp | `core/variant/variant_utility.cpp` | push_error実装（1018-1026行目） |

**主要処理フロー**:
1. **1018行目**: 関数定義開始
2. **1019-1022行目**: 引数数チェック（最低1つ必要）
3. **1024行目**: ERR_PRINTマクロ呼び出し（join_stringで引数連結）
4. **1025行目**: CallError::CALL_OK設定

#### Step 3: エラー出力処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | error_macros.cpp | `core/error/error_macros.cpp` | _err_print_error実装（106-135行目） |
| 3-2 | os.cpp | `core/os/os.cpp` | OS::print_error実装（97-105行目） |

**主要処理フロー**:
- **106行目**: メインエラー出力関数
- **107-112行目**: 再帰呼び出し防止チェック
- **116-117行目**: OS::print_error呼び出し
- **124-130行目**: ErrorHandlerList通知ループ

#### Step 4: Logger処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | logger.cpp | `core/io/logger.cpp` | Logger::log_error実装（58-80行目） |
| 4-2 | logger.h | `core/io/logger.h` | ErrorType列挙型（50-55行目） |

**主要処理フロー**:
- **58行目**: log_error関数定義
- **63-70行目**: エラー詳細文字列の決定
- **72-73行目**: エラータイプと詳細の出力
- **75-79行目**: スクリプトバックトレースの出力

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

```
push_error(args...)  [GDScript]
    │
    └─ VariantUtilityFunctions::push_error(p_args, p_arg_count)
           │
           ├─ join_string(p_args, p_arg_count)  →  エラーメッセージ連結
           │
           └─ ERR_PRINT(joined_message)
                  │
                  └─ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, message)
                         │
                         ├─ 再帰呼び出しチェック
                         │
                         └─ OS::get_singleton()->print_error(...)
                                │
                                ├─ Logger::log_error(...)
                                │      │
                                │      ├─ logf_error("ERROR: %s")
                                │      │
                                │      └─ スクリプトバックトレース出力
                                │
                                └─ ErrorHandlerList通知
                                       │
                                       └─ 各ハンドラのerrfunc呼び出し
```

### データフロー図

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

p_args[0..n]     ───▶  join_string()  ───▶  message(String)
(Variant**)                                      │
                                                 │
                                           ERR_PRINT()
                                                 │
                                           _err_print_error()
                                                 │
                              ┌──────────────────┼──────────────────┐
                              ▼                  ▼                  ▼
                      OS::print_error()  ErrorHandlerList    フォールバック
                              │                  │                  │
                       Logger::log_error()  各ハンドラ          stderr
                              │                  │
                    ┌─────────┼─────────┐        │
                    ▼         ▼         ▼        ▼
               stdout    logfile    stderr   EditorToaster等
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| variant_utility.h | `core/variant/variant_utility.h` | ソース | push_error関数宣言 |
| variant_utility.cpp | `core/variant/variant_utility.cpp` | ソース | push_error実装、引数連結処理 |
| error_macros.h | `core/error/error_macros.h` | ソース | ERR_PRINTマクロ定義 |
| error_macros.cpp | `core/error/error_macros.cpp` | ソース | _err_print_error実装 |
| logger.h | `core/io/logger.h` | ソース | Logger基底クラス、ErrorType定義 |
| logger.cpp | `core/io/logger.cpp` | ソース | Logger::log_error実装 |
| os.h | `core/os/os.h` | ソース | OS::print_error宣言 |
| os.cpp | `core/os/os.cpp` | ソース | OS::print_error実装 |
