# 画面設計書 70-500エラー（Oops）

## 概要

本ドキュメントは、Jenkins CI/CDサーバーの「500エラー（Oops）」画面の設計書です。

### 本画面の処理概要

サーバー内部でエラーが発生した場合に表示されるエラー画面です。HTTPステータスコード500（Internal Server Error）に対応します。

**業務上の目的・背景**：Jenkinsサーバー内部で予期しない例外が発生した場合に、ユーザーフレンドリーなエラーメッセージを表示し、必要に応じてスタックトレースを提供することを目的としています。スタックトレースはバグ報告やトラブルシューティングに役立ちます。この画面は、開発者や管理者が問題を特定し、JIRAへのバグ報告を行うための情報を提供します。

**画面へのアクセス方法**：サーバー内部でキャッチされない例外が発生した際に自動的に表示されます。web.xmlで500エラーハンドラとして設定されています。UncaughtExceptionHandlerによっても呼び出されます。

**主要な操作・処理内容**：
1. エラーメッセージの表示
2. ロギングIDの表示（ログ追跡用）
3. スタックトレースの表示（設定により）
4. スタックトレースのコピー機能

**画面遷移**：この画面からの遷移はありません（エラー終点）

**権限による表示制御**：スタックトレースの表示は `Jenkins.shouldShowStackTrace()` により制御されます。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | Jenkins本体 | 主機能 | 内部エラーの表示 |

## 画面種別

エラー

## URL/ルーティング

- URL: 任意のURLで500エラー発生時
- ルーティング: web.xmlの `<error-page>` 設定およびUncaughtExceptionHandlerにより `oops.jelly` が呼び出されます

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| - | - | - | - | この画面には入力項目はありません |

## 表示項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| rage.svg | 画像 | 怒り顔の感情アイコン |
| Oops! | 見出し | エラー見出し |
| problemHappened | テキスト | 問題発生メッセージ |
| Logging ID | テキスト | ログ追跡用の一意識別子 |
| checkJIRA等 | テキスト | バグ報告の案内（スタックトレース表示時） |
| Stack trace | 見出し | スタックトレースセクション見出し |
| copyButton | ボタン | スタックトレースコピーボタン |
| stacktrace | コード | 例外のスタックトレース |

## イベント仕様

### 1-画面表示

500エラー発生時に自動的に呼び出されます。

**処理フロー**：
1. `st:statusCode` でHTTPステータスコードを設定（response2.getStatus()）
2. エラーメッセージ（problemHappened）を表示
3. ロギングIDを表示（jenkins.exception.id属性から取得）
4. `app.shouldShowStackTrace()` がtrueの場合：
   - バグ報告案内を表示
   - スタックトレースを取得・表示
   - コピーボタンを表示

### 2-コピーボタン押下

スタックトレースをクリップボードにコピーします。

**処理フロー**：
1. `l:copyButton` コンポーネントがクリックイベントを処理
2. stacktrace変数の内容をクリップボードにコピー

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | なし | なし | データベースアクセスなし |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|---------|
| Oops! | 見出し | Oops! | 常時表示 |
| problemHappened | メッセージ | 問題が発生したことを示すメッセージ | 常時表示 |
| Logging ID= | テキスト | Logging ID={id} | 常時表示 |
| checkJIRA | メッセージ | JIRAを確認するよう促すメッセージ | スタックトレース表示時 |
| vote | メッセージ | 既存バグへの投票を促すメッセージ | スタックトレース表示時 |
| pleaseReport | メッセージ | 新規バグ報告を促すメッセージ | スタックトレース表示時 |
| stackTracePlease | メッセージ | スタックトレースを含めるよう促すメッセージ | スタックトレース表示時 |
| checkML | メッセージ | メーリングリストを確認するよう促すメッセージ | スタックトレース表示時 |
| Stack trace | 見出し | Stack trace | スタックトレース表示時 |

## 例外処理

| 例外条件 | 対応 | 表示内容 |
|---------|------|---------|
| - | - | この画面自体がエラー処理画面のため、特別な例外処理はありません |

## 備考

- この画面はweb.xmlで500エラーページとして設定されており、UncaughtExceptionHandlerからも呼び出されます
- ロギングIDはサーバーログとの照合に使用され、ログから詳細な情報を確認できます
- スタックトレースの表示は `Jenkins.shouldShowStackTrace()` で制御されます
- `rage.svg` は怒った顔の絵文字アイコンです
- 例外オブジェクトは `jakarta.servlet.error.exception` 属性から取得されます
- `h.printThrowable()` メソッドで例外を文字列化しています

---

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

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

### 推奨読解順序

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

まず、エラー画面の構造と設定を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | web.xml | `core/src/main/resources/WEB-INF/web.xml` | error-page設定を確認 |
| 1-2 | UncaughtExceptionHandler.java | `core/src/main/java/hudson/util/UncaughtExceptionHandler.java` | 例外ハンドリングの仕組みを理解 |

**読解のコツ**: 500エラーはweb.xmlの設定とUncaughtExceptionHandlerの両方で処理されます。ロギングIDはUncaughtExceptionHandlerで生成されます。

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

画面表示の起点となるファイルを特定します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | oops.jelly | `core/src/main/resources/jenkins/model/Jenkins/oops.jelly` | 画面構造、条件分岐、スタックトレース表示を理解 |

**主要処理フロー**:
1. **行30**: `st:statusCode value="${response2.getStatus()}"` でステータスコード設定
2. **行31**: one-columnレイアウト
3. **行34-35**: rage.svgアイコンとOops!見出しの表示
4. **行37-40**: problemHappenedメッセージとロギングID
5. **行41-49**: スタックトレース表示部分（条件付き）

#### Step 3: スタックトレース表示を理解する

スタックトレースの取得と表示処理を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | oops.jelly (スタックトレース部分) | 同上 | h.printThrowable()、l:copyButtonの使い方を理解 |

**主要処理フロー**:
- **行41**: `app.shouldShowStackTrace()` で表示制御
- **行42**: バグ報告案内メッセージ
- **行43**: 例外を `h.printThrowable()` で文字列化
- **行44-47**: "Stack trace" 見出しとコピーボタン
- **行48**: preタグでスタックトレース表示

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

```
[500エラー発生]
    │
    ├─ UncaughtExceptionHandler ─── ロギングID生成
    │      │
    │      └─ request.setAttribute('jenkins.exception.id', id)
    │
    └─ web.xml (error-page設定)
           │
           └─ oops.jelly
                  │
                  ├─ st:statusCode ─────── HTTPステータス設定
                  │
                  ├─ l:layout ─────────── レイアウト設定
                  │
                  ├─ rage.svg + "Oops!" ── アイコンと見出し
                  │
                  ├─ ${%problemHappened} ─ エラーメッセージ
                  │
                  ├─ Logging ID ─────────── ログ追跡用ID
                  │
                  └─ j:if shouldShowStackTrace()
                         │
                         ├─ ${%checkJIRA} etc. ── バグ報告案内
                         │
                         ├─ h.printThrowable() ── スタックトレース取得
                         │
                         ├─ l:copyButton ──────── コピー機能
                         │
                         └─ <pre> ──────────────── スタックトレース表示
```

### データフロー図

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

例外発生 ─────────────▶ UncaughtExceptionHandler
                              │
                              ├─ ロギングID生成 ─────────▶ jenkins.exception.id
                              │
                              └─ ログ出力
                                    │
                                    ▼
                        web.xml error-page
                              │
                              ▼
                        oops.jelly
                              │
                              ├─ response2.getStatus() ────▶ HTTPステータス
                              │
                              ├─ jenkins.exception.id ─────▶ ロギングID表示
                              │
                              ├─ jakarta.servlet.error.exception
                              │      │
                              │      └─ h.printThrowable() ─▶ スタックトレース
                              │
                              └─ l:copyButton ─────────────▶ コピー機能
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| oops.jelly | `core/src/main/resources/jenkins/model/Jenkins/oops.jelly` | テンプレート | 500エラー画面テンプレート |
| oops.properties | `core/src/main/resources/jenkins/model/Jenkins/oops.properties` | 設定 | メッセージ定義 |
| web.xml | `core/src/main/resources/WEB-INF/web.xml` | 設定 | エラーページ設定 |
| UncaughtExceptionHandler.java | `core/src/main/java/hudson/util/UncaughtExceptionHandler.java` | ソース | 例外ハンドラ |
| Functions.java | `core/src/main/java/hudson/Functions.java` | ソース | printThrowable()を含む |
| _404.jelly | `core/src/main/resources/jenkins/model/Jenkins/_404.jelly` | テンプレート | 404エラー画面（類似実装） |
| rage.svg | `war/src/main/webapp/images/rage.svg` | 画像 | エラーアイコン |
| copyButton.jelly | `core/src/main/resources/lib/layout/copyButton.jelly` | テンプレート | コピーボタンコンポーネント |
