# 画面設計書 8-例外情報

## 概要

本ドキュメントは、Apache Flink Web Dashboardの例外情報画面の設計仕様を記述したものである。本画面はジョブ実行中に発生した例外・エラー情報を表示する。

### 本画面の処理概要

例外情報画面は、ジョブ実行中に発生した例外やエラーの詳細情報を表示する。最新の例外のスタックトレースをコードエディター形式で表示するとともに、例外履歴を一覧形式で表示し、過去のエラー情報にもアクセスできる。

**業務上の目的・背景**：ストリーム処理ジョブで発生したエラーの原因究明は運用上極めて重要である。本画面により、開発者や運用者は例外のスタックトレース、発生タイミング、発生したTaskManagerの情報を確認し、迅速な問題解決が可能になる。

**画面へのアクセス方法**：ジョブ詳細画面の「Exceptions」タブをクリック、または`/job/:status/:jid/exceptions`パスに直接アクセスする。

**主要な操作・処理内容**：
1. ルート例外（最新の例外）のスタックトレース表示
2. 例外履歴の一覧表示
3. 同時発生例外の選択・切り替え
4. 例外発生TaskManagerへの遷移
5. 追加例外の読み込み（Load More）

**画面遷移**：
- 遷移元：ジョブ詳細画面
- 遷移先：TaskManagerメトリクス画面（`/task-manager/:taskManagerId/metrics`）

**権限による表示制御**：本画面に関しては、特別な権限制御は実装されていない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 32 | REST API | 主機能 | ジョブ例外情報の取得・表示（/jobs/{jobid}/exceptions API） |
| 23 | ジョブ管理 | 補助機能 | 例外履歴の一覧表示とスタックトレース詳細表示 |
| 24 | タスク実行 | 遷移先機能 | 例外発生TaskManagerへの画面遷移 |

## 画面種別

詳細 / 一覧

## URL/ルーティング

- パス: `/job/:status/:jid/exceptions`

## 入出力項目

| 項目名 | 種別 | データ型 | 説明 |
|--------|------|----------|------|
| jid | URLパラメータ | string | ジョブID（親から継承） |

## 表示項目

### ルート例外タブ

| 項目名 | データ型 | 説明 | 取得元 |
|--------|----------|------|--------|
| 例外メッセージ | string | フォーマット済みの例外情報（タイムスタンプ + スタックトレース） | `/jobs/{jobid}/exceptions` API |

### 例外履歴タブ

| 項目名 | データ型 | 説明 | 取得元 |
|--------|----------|------|--------|
| タイムスタンプ | timestamp | 例外発生日時 | `/jobs/{jobid}/exceptions` API |
| タスク名 | string | 例外が発生したタスク名（グローバル失敗の場合は"(global failure)"） | 同上 |
| TaskManager | string | 例外が発生したTaskManager ID | 同上 |
| スタックトレース | string | 例外のスタックトレース | 同上 |
| 同時発生例外 | ExceptionInfo[] | 同時に発生した他の例外 | 同上 |
| ラベル | object | 例外に付与されたラベル情報 | 同上 |

## イベント仕様

### 1-画面初期化

**トリガー**: コンポーネント初期化時（ngOnInit）

**処理フロー**:
1. loadMore()を呼び出して初回データ取得
2. maxExceptionsを10に設定

### 2-例外情報取得

**トリガー**: loadMore()呼び出し

**処理フロー**:
1. isLoadingをtrueに設定
2. maxExceptionsを10増加
3. JobLocalService.jobDetailChanges()からジョブIDを取得
4. JobService.loadExceptions()で例外情報を取得
5. 最新の例外をrootExceptionに設定
6. exceptionHistoryを構築（同時発生例外を含む）
7. truncatedフラグを確認

**API呼び出し**:
- GET `/jobs/{jobid}/exceptions?maxExceptions={maxExceptions}`

### 3-TaskManager遷移

**トリガー**: TaskManager IDのリンクをクリック

**処理フロー**:
1. navigateTo()が呼び出される
2. taskManagerIdがnullでない場合、Router.navigate()で遷移

**遷移先**: `/task-manager/{taskManagerId}/metrics`

### 4-同時発生例外切り替え

**トリガー**: 例外履歴の同時発生例外セレクターで選択変更

**処理フロー**:
1. 選択された例外をselectedプロパティに設定
2. 画面表示を更新

### 5-追加読み込み

**トリガー**: 「Load More」ボタンクリック

**処理フロー**:
1. loadMore()を再呼び出し
2. maxExceptionsが増加し、より多くの履歴を取得

## データベース更新仕様

本画面はデータ参照のみを行い、データベースへの更新処理は発生しない。

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 該当なし | - | SELECT | 全ての操作は参照のみ |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| no-exception | 情報 | "No Root Exception" | 例外履歴が空の場合 |

## 例外処理

| 例外種別 | 発生条件 | 処理内容 |
|----------|----------|----------|
| API通信エラー | 例外情報取得失敗 | エラーハンドリングなし（画面が更新されない） |

## 備考

- コードエディターにはng-zorro-antdのNzCodeEditorModuleを使用
- エディターオプションはflinkEditorOptions（読み取り専用設定）
- 同時発生例外（concurrentExceptions）の処理にはstripConcurrentExceptions関数を使用
- グローバル失敗の場合、taskNameがnullになるため、markGlobalFailure関数で"(global failure)"を設定
- 例外履歴は展開可能なパネル形式で表示

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | job-exception.ts | `src/app/interfaces/job-exception.ts` | ExceptionInfo型、RootExceptionInfo型の定義 |

**読解のコツ**: RootExceptionInfoはconcurrentExceptionsプロパティを持つ。これは同時に発生した他の例外の配列である。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | job-exceptions.component.ts | `src/app/pages/job/exceptions/job-exceptions.component.ts` | メインコンポーネント |

**主要処理フロー**:
1. **112-114行目**: ngOnInit()でloadMore()を呼び出し
2. **121-156行目**: loadMore()で例外情報を取得・加工
3. **58-68行目**: stripConcurrentExceptions()とmarkGlobalFailure()ヘルパー関数
4. **147-154行目**: exceptionHistoryの構築ロジック

#### Step 3: サービス層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | job.service.ts | `src/app/services/job.service.ts` | loadExceptions()メソッド |

**主要処理フロー**:
- **110-114行目**: loadExceptions() - maxExceptionsパラメータを含むAPIリクエスト

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

```
JobExceptionsComponent
    │
    ├─ ngOnInit()
    │      └─ loadMore()
    │
    ├─ JobLocalService.jobDetailChanges()
    │      └─ ジョブIDの取得
    │
    ├─ JobService.loadExceptions()
    │      └─ GET /jobs/{jobid}/exceptions?maxExceptions=N
    │
    ├─ stripConcurrentExceptions()
    │      └─ 同時発生例外の分離
    │
    ├─ markGlobalFailure()
    │      └─ グローバル失敗のラベル付け
    │
    └─ Router.navigate()
           └─ TaskManager画面への遷移
```

### データフロー図

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

loadMore()呼び出し ─────▶ JobService.loadExceptions()
                              │
                              ▼
                        /jobs/{jobid}/exceptions
                              │
                              ▼
                        exceptionHistory構築
                              │
                              ├─▶ stripConcurrentExceptions()
                              │
                              └─▶ markGlobalFailure()
                                    │
                                    ▼
                        ┌─────────────────────────┐
                        │                         │
                        ▼                         ▼
                  rootException            exceptionHistory[]
                  (コードエディター)        (一覧テーブル)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| job-exceptions.component.ts | `src/app/pages/job/exceptions/job-exceptions.component.ts` | ソース | メインコンポーネント |
| job-exceptions.component.html | `src/app/pages/job/exceptions/job-exceptions.component.html` | テンプレート | レイアウト |
| job-exceptions.component.less | `src/app/pages/job/exceptions/job-exceptions.component.less` | スタイル | スタイル定義 |
| job.service.ts | `src/app/services/job.service.ts` | ソース | 例外情報取得 |
| job-exception.ts | `src/app/interfaces/job-exception.ts` | 型定義 | 例外データ型 |
| job-local.service.ts | `src/app/pages/job/job-local.service.ts` | ソース | データ共有 |
| editor-config.ts | `src/app/components/editor/editor-config.ts` | 設定 | エディターオプション |
