# 機能設計書 62-例外機構

## 概要

本ドキュメントは、Juliaにおける構造化例外処理機構（`try` / `catch` / `finally` / `throw` / `rethrow`）の設計と実装を記述するものである。

### 本機能の処理概要

本機能は、Julia言語の構造化例外処理を提供する。`throw` による例外の送出、`try` / `catch` によるキャッチ、`finally` による後処理保証、`rethrow` による例外の再送出を実現する。

**業務上の目的・背景**：プログラム実行中に発生するエラーを構造的に処理し、プログラムの堅牢性を確保する。例外処理がなければ、エラー発生時にプログラムが即座に終了してしまい、リソースの解放やエラーの適切な報告が行えない。JuliaのREPLや長時間実行するサーバーアプリケーションにおいて、エラーからの回復を可能にする基盤機能である。

**機能の利用シーン**：ファイルI/O操作でのエラーハンドリング、ネットワーク通信のタイムアウト処理、REPL評価ループでのエラー回復、パッケージのロード失敗時の処理、ユーザー入力のバリデーションエラー処理などで利用される。

**主要な処理内容**：
1. `throw(e)` による例外オブジェクトの送出とバックトレースの記録
2. `try` / `catch` ブロックによる例外の捕捉と型ベースのフィルタリング
3. `finally` ブロックによるリソース解放の保証
4. `rethrow()` / `rethrow(e)` による例外の再送出
5. `current_exceptions()` によるネストされた例外スタックの取得
6. `backtrace()` / `catch_backtrace()` によるスタックトレース取得

**関連システム・外部連携**：Cランタイム（`jl_rethrow`, `jl_backtrace_from_here`, `jl_get_backtrace`, `jl_get_excstack`）との連携。

**権限による制御**：なし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Juliaプロンプト（julia>） | 参照画面 | try/catchによるREPL評価ループ内のエラーハンドリング |
| 11 | フォールバックREPL | 参照画面 | try/catchによるREPLループ内のエラーハンドリング |

## 機能種別

制御構造 / ランタイム機能

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| e | `Any` | Yes（throwの場合） | 送出する例外オブジェクト | 任意のオブジェクトが送出可能 |
| task | `Task` | No | `current_exceptions` の対象タスク | デフォルトは `current_task()` |
| backtrace | `Bool` | No | バックトレースを含めるか | デフォルト `true` |

### 入力データソース

ランタイムの実行コンテキスト（コールスタック、例外スタック）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| backtrace | `Vector{Union{InterpreterIP, Ptr{Cvoid}}}` | バックトレース情報 |
| exception_stack | `ExceptionStack` | 現在の例外スタック |

### 出力先

例外は呼び出し元の `catch` ブロックへ伝播する。

## 処理フロー

### 処理シーケンス

```
1. throw(e) の実行
   └─ 例外オブジェクトとバックトレースをランタイムに登録
2. スタックの巻き戻し（unwinding）
   └─ 最も内側の try ブロックまでスタックを巻き戻す
3. catch ブロックのマッチング
   └─ 例外の型による条件マッチを行い、一致する catch ブロックを実行
4. finally ブロックの実行
   └─ try/catch の終了時に必ず実行（例外の有無に関係なく）
5. 未キャッチ例外の伝播
   └─ catch されなかった例外は上位の try ブロックに伝播
```

### フローチャート

```mermaid
flowchart TD
    A[throw e] --> B[バックトレース記録]
    B --> C[スタック巻き戻し]
    C --> D{catch ブロック存在?}
    D -->|Yes| E{型マッチ?}
    D -->|No| F[タスク終了/トップレベルエラー]
    E -->|Yes| G[catch ブロック実行]
    E -->|No| C
    G --> H{finally あり?}
    H -->|Yes| I[finally 実行]
    H -->|No| J[正常継続]
    I --> J
    F --> K{finally あり?}
    K -->|Yes| L[finally 実行]
    K -->|No| M[エラー表示]
    L --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-62-01 | 例外伝播 | 未キャッチの例外は呼び出しスタックを遡って伝播する | catch されなかった場合 |
| BR-62-02 | finally 保証 | finally ブロックは例外の有無に関係なく必ず実行される | try ブロック終了時 |
| BR-62-03 | rethrow 制限 | rethrow() は catch ブロック内でのみ使用可能 | catch ブロック内 |
| BR-62-04 | ネスト例外 | ネストされた catch ブロックでは例外スタックに積まれる | Julia 1.1以降 |

### 計算ロジック

該当なし。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | UndefVarError | catch ブロック外で rethrow() を呼んだ場合 | catch ブロック内で使用する |

### リトライ仕様

本機能自体にリトライ機構はない（リトライは No.65 を参照）。

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

該当なし。

## パフォーマンス要件

- 例外が発生しないパス（happy path）ではゼロコスト
- 例外発生時のスタック巻き戻しはスタック深度に比例

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

例外オブジェクトに機密情報が含まれる可能性があるため、例外の表示・ログ出力時に注意が必要。

## 備考

- Julia の例外処理は Lisp スタイルのダイナミックスコープベースである
- `try` / `catch` / `finally` は Core 言語機能としてコンパイラが直接サポートする

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | error.jl | `base/error.jl` | `InterpreterIP` 構造体（76-80行目）: インタプリタフレームのIP表現 |
| 1-2 | error.jl | `base/error.jl` | `ExceptionStack` 構造体（140-142行目）: ネストされた例外スタックの表現 |

**読解のコツ**: `InterpreterIP` はバックトレースの各フレームを表現する。`code` フィールドは `CodeInfo`, `MethodInstance`, `CodeInstance`, `Nothing` のいずれか。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | error.jl | `base/error.jl` | `throw` 関数（19-26行目）: 例外送出のドキュメントとJuliaレベルの定義 |
| 2-2 | error.jl | `base/error.jl` | `rethrow` 関数（60-74行目）: 例外再送出の実装（ccallでランタイムに委譲） |

**主要処理フロー**:
1. **73行目**: `rethrow()` は `ccall(:jl_rethrow, Bottom, ())` でCランタイムに委譲
2. **74行目**: `rethrow(e)` は `ccall(:jl_rethrow_other, Bottom, (Any,), e)` で代替例外を送出

#### Step 3: バックトレース取得を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | error.jl | `base/error.jl` | `backtrace()` 関数（117-128行目）: 現在のプログラムポイントのバックトレース取得 |
| 3-2 | error.jl | `base/error.jl` | `catch_backtrace()` 関数（130-138行目）: 現在の例外のバックトレース取得 |
| 3-3 | error.jl | `base/error.jl` | `_reformat_bt` 関数（84-114行目）: ネイティブ/インタプリタフレームの統合 |

#### Step 4: 例外スタックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | error.jl | `base/error.jl` | `current_exceptions` 関数（144-172行目）: ネストされた例外スタックの取得 |

**主要処理フロー**:
- **163行目**: `ccall(:jl_get_excstack, ...)` でランタイムから例外スタックを取得
- **164-171行目**: NamedTuple 形式に整形して ExceptionStack として返却

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

```
throw(e)                          [Core/ランタイム]
    │
    ├─ jl_throw()                 [src/task.c]
    │      └─ jl_eh_restore()     スタック巻き戻し
    │
rethrow()
    └─ jl_rethrow()               [src/task.c]

backtrace()
    └─ jl_backtrace_from_here()   [src/stackwalk.c]
         └─ _reformat_bt()        [base/error.jl]

catch_backtrace()
    └─ jl_get_backtrace()         [src/stackwalk.c]
         └─ _reformat_bt()        [base/error.jl]

current_exceptions(task)
    └─ jl_get_excstack()          [src/task.c]
```

### データフロー図

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

例外オブジェクト ──▶ throw() ──▶ ランタイム例外スタック
                         │
                         ▼
                    スタック巻き戻し ──▶ catch ブロック
                         │
                         ▼
                    backtrace() ──▶ Vector{Union{InterpreterIP, Ptr{Cvoid}}}
                         │
                         ▼
                    current_exceptions() ──▶ ExceptionStack
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| error.jl | `base/error.jl` | ソース | 例外処理のJuliaレベル実装 |
| task.c | `src/task.c` | ソース（C） | 例外のスロー・巻き戻しのランタイム実装 |
| stackwalk.c | `src/stackwalk.c` | ソース（C） | バックトレース取得のランタイム実装 |
| julia.h | `src/julia.h` | ヘッダ | 例外関連のデータ構造定義 |
| stacktraces.jl | `base/stacktraces.jl` | ソース | スタックトレースのJuliaレベルAPI |
