# 機能設計書 98-Exception

## 概要

本ドキュメントは、VBCorLibライブラリにおけるException機能の設計を記述するものである。Exceptionは、すべての例外クラスの基底クラスであり、例外処理の共通インターフェースを定義する。

### 本機能の処理概要

Exceptionクラスは、エラー情報を格納し伝播するための構造化された例外処理メカニズムを提供する。エラーメッセージ、原因となった内部例外、HResult、ソース情報などを保持し、例外の連鎖をサポートする。

**業務上の目的・背景**：VB6/VBAの標準的なエラー処理（On Error）を拡張し、.NET Framework互換の構造化例外処理を提供する。これにより、エラー情報の詳細な伝達、例外の階層化、より堅牢なエラーハンドリングが可能になる。

**機能の利用シーン**：アプリケーション全体での統一的なエラーハンドリング、例外の種類に基づいた分岐処理、エラー情報のログ出力、例外チェーンによる根本原因の追跡に使用される。

**主要な処理内容**：
1. エラー情報の保持（Message/HResult/ErrorNumber/Source）
2. 例外チェーン（InnerException/GetBaseException）
3. ユーザー定義データの保持（Data）
4. 文字列表現（ToString）
5. シリアライズ対応（PropertyBag経由）

**関連システム・外部連携**：VB6のErr.Raiseと連携してThrow/Catchパターンを実現。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面機能マッピングに直接の関連なし（内部クラス） |

## 機能種別

エラー処理 / 基底クラス

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Message | String | No | エラーメッセージ | - |
| ErrorNumber | Long | No | VBエラー番号 | - |
| InnerException | Exception | No | 原因となった内部例外 | - |

### 入力データソース

- アプリケーションコードからの直接生成
- VBCorLib内部での例外生成

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Message | String | エラーメッセージ |
| HResult | Long | HRESULT値（COR_E_EXCEPTION） |
| ErrorNumber | Long | VBエラー番号 |
| Source | String | エラー発生元 |
| HelpLink | String | ヘルプファイルへのリンク |
| InnerException | Exception | 内部例外 |
| Data | IDictionary | ユーザー定義データ |
| ToString | String | 例外の文字列表現 |

### 出力先

- 呼び出し元への戻り値
- ログ出力用の文字列

## 処理フロー

### 処理シーケンス

```
1. Exception生成
   └─ NewExceptionでインスタンス生成
   └─ ExceptionBaseに委譲して初期化
   └─ Message、ErrorNumber、InnerExceptionを設定

2. プロパティアクセス
   └─ mBase経由で各プロパティを取得/設定

3. GetBaseException呼び出し
   └─ InnerExceptionが存在する場合は再帰的に辿る
   └─ 最も内側の例外を返却

4. ToString呼び出し
   └─ 型名 + ": " + Messageの形式で文字列生成
   └─ InnerExceptionがあれば連結
```

### フローチャート

```mermaid
flowchart TD
    A[NewException] --> B[ExceptionBase生成]
    B --> C[Message設定]
    C --> D[ErrorNumber設定]
    D --> E[InnerException設定]
    E --> F[Exceptionオブジェクト返却]
    F --> G{GetBaseException?}
    G -->|Yes| H{InnerException存在?}
    H -->|Yes| I[InnerException.GetBaseException]
    H -->|No| J[自身を返却]
    I --> J
    G -->|No - ToString| K[型名 + Message生成]
    K --> L{InnerException存在?}
    L -->|Yes| M[InnerException.ToString追加]
    L -->|No| N[文字列返却]
    M --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-98-01 | デフォルトHResult | HResultはCOR_E_EXCEPTIONを返却 | HResultアクセス時 |
| BR-98-02 | デフォルトErrorNumber | ErrorNumberのデフォルトはvbInvalidProcedureCall | 初期化時 |
| BR-98-03 | 例外チェーン | GetBaseExceptionはチェーンを辿って最も内側の例外を返却 | GetBaseException呼び出し時 |
| BR-98-04 | ToString形式 | "型名: メッセージ" + InnerExceptionの形式 | ToString呼び出し時 |

### 計算ロジック

特になし

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

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

該当なし

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

該当なし

## エラー処理

### エラーケース一覧

Exceptionクラス自体は例外を発生させない（例外の基底クラスとして例外情報を保持するのみ）。

### リトライ仕様

特になし

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

該当なし

## パフォーマンス要件

- 例外オブジェクトの生成は比較的軽量
- ToStringは例外チェーンが深い場合に時間がかかる可能性あり

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

- エラーメッセージに機密情報を含めないこと
- ユーザー向けには一般的なエラーメッセージを表示し、詳細はログに記録

## 備考

- .NET FrameworkのSystem.Exceptionクラスに対応
- VBCorLibのThrow/Catchパターンで使用
- Persistable属性により、PropertyBag経由でシリアライズ可能

---

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

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

### 推奨読解順序

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

ExceptionとExceptionBaseの関係を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Exception.cls | `Source/CorLib/System/Exception.cls` | mBase変数（94行目）がExceptionBaseへの参照を保持 |
| 1-2 | ExceptionBase.cls | `Source/CorLib/System/ExceptionBase.cls` | 実際のプロパティ値を保持（60-69行目） |

**読解のコツ**: Exceptionクラスは薄いラッパーで、ほとんどの処理はExceptionBaseに委譲される。

#### Step 2: 初期化処理を理解する

例外オブジェクトの生成と初期化を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Exception.cls | `Source/CorLib/System/Exception.cls` | Class_InitProperties（255-258行目）でExceptionBase生成 |
| 2-2 | Exception.cls | `Source/CorLib/System/Exception.cls` | Init（260-264行目）でMessage、ErrorNumber、InnerException設定 |

**主要処理フロー**:
- **255-258行目**: Class_InitProperties - Cor.NewExceptionBaseでExceptionBaseを生成し、ErrorNumberを設定
- **260-264行目**: Init - Message、ErrorNumber、InnerExceptionをmBaseに設定

#### Step 3: プロパティアクセスを理解する

各プロパティの取得・設定がExceptionBaseに委譲される仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Exception.cls | `Source/CorLib/System/Exception.cls` | Message（184-186行目）でGetExceptionMessageを使用 |
| 3-2 | ExceptionBase.cls | `Source/CorLib/System/ExceptionBase.cls` | Message（186-188行目）でmMessageを返却 |

**主要処理フロー**:
- **184-186行目**: Message Get - GetExceptionMessageヘルパー関数経由で取得
- **114-127行目**: HelpLink - mBase.HelpLinkに委譲
- **146-148行目**: ErrorNumber - mBase.ErrorNumberに委譲

#### Step 4: 例外チェーンを理解する

GetBaseExceptionの再帰的な実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Exception.cls | `Source/CorLib/System/Exception.cls` | GetBaseException（213-215行目）でmBase.GetBaseExceptionを呼び出し |
| 4-2 | ExceptionBase.cls | `Source/CorLib/System/ExceptionBase.cls` | GetBaseException（289-295行目）で再帰的に辿る |

**主要処理フロー**:
- **289-295行目**: ExceptionBase.GetBaseException - InnerExceptionがNothingなら自身を返却、そうでなければInnerException.GetBaseExceptionを再帰呼び出し

#### Step 5: シリアライズを理解する

PropertyBagによるシリアライズを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Exception.cls | `Source/CorLib/System/Exception.cls` | Class_ReadProperties/Class_WriteProperties（270-276行目） |
| 5-2 | ExceptionBase.cls | `Source/CorLib/System/ExceptionBase.cls` | Class_ReadProperties/Class_WriteProperties（371-399行目） |

**主要処理フロー**:
- **270-272行目**: Class_ReadProperties - PropertyBagからmBaseを読み込み
- **274-276行目**: Class_WriteProperties - PropertyBagにmBaseを書き込み

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

```
NewException
    │
    └─ Exception.Init
           │
           └─ ExceptionBase設定
                  ├─ Message設定
                  ├─ ErrorNumber設定
                  └─ InnerException設定

Exception.Message
    │
    └─ GetExceptionMessage
           │
           └─ ExceptionBase.Message

Exception.GetBaseException
    │
    └─ ExceptionBase.GetBaseException
           │
           └─ InnerException.GetBaseException（再帰）

Exception.ToString
    │
    └─ ExceptionBase.ToString
           │
           ├─ TypeName取得
           ├─ Message取得
           └─ InnerException.ToString（存在時）
```

### データフロー図

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

Message ─────────────────▶ Exception.Init ──────────────▶ mBase.Message設定
ErrorNumber ─────────────┘      │
InnerException ──────────────────┘

（なし） ─────────────────▶ Exception.Message ──────────▶ エラーメッセージ
                                │
                                ▼
                         GetExceptionMessage
                                │
                                ▼
                         mBase.Message

（なし） ─────────────────▶ GetBaseException ──────────▶ 最も内側の例外
                                │
                                ▼
                         InnerException辿り
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Exception.cls | `Source/CorLib/System/Exception.cls` | ソース | 例外基底クラス |
| ExceptionBase.cls | `Source/CorLib/System/ExceptionBase.cls` | ソース | 例外実装のヘルパークラス |
| ArgumentException.cls | `Source/CorLib/System/ArgumentException.cls` | ソース | 派生クラス例 |
| ArgumentNullException.cls | `Source/CorLib/System/ArgumentNullException.cls` | ソース | 派生クラス例 |
