# 通知設計書 8-致命的エラー通知

## 概要

本ドキュメントは、Bun の Hot Module Reloading (HMR) 機能において、致命的エラー（fatal error）が発生した際に設定されるフラグと、それに伴う次回ビルド成功時のページリロード動作の設計を記載する。

### 本通知の処理概要

致命的エラー通知は、オーバーレイ UI に直接表示される「メッセージ」ではなく、`hasFatalError` フラグによる内部状態管理とそれに基づくリロード制御の仕組みである。ランタイムエラーが発生した際にこのフラグが true に設定され、次回の hot_update メッセージ受信時（ビルド成功時）にページの完全リロードがトリガーされる。

**業務上の目的・背景**：ランタイムエラーが発生した後、HMR だけでは状態を完全にリセットできない場合がある。特に、エラーによってアプリケーションの状態が破損した場合、差分更新（HMR）だけでは正常な動作を回復できない。`hasFatalError` フラグにより、次回のビルド成功時に自動的にページ全体をリロードし、クリーンな状態からアプリケーションを再起動することで、開発者が手動でリロードする手間を省く。

**通知の送信タイミング**：`hasFatalError` フラグは `onRuntimeError` 関数が呼び出された際（`fatal = true` パラメータ付き）に設定される。このフラグの効果は、`hot_update` メッセージ受信時に発動し、更新内容がある場合に `fullReload()` を実行する。

**通知の受信者**：直接的な通知メッセージは表示されない。開発者は、ビルド成功後にページが自動的にリロードされることで、致命的エラーからの回復が行われたことを間接的に認識する。

**通知内容の概要**：UI 上の直接的な通知はないが、`hasFatalError` が true の状態でビルドが成功すると、自動的に `fullReload()` が実行され、ページ全体が再読み込みされる。

**期待されるアクション**：開発者はランタイムエラーを修正後、ファイルを保存する。DevServer がインクリメンタルビルドを実行し、ビルドが成功すると自動的にページがリロードされる。特別なアクションは不要。

## 通知種別

内部状態フラグ（自動リロード制御）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 該当なし（内部状態フラグ） |
| 優先度 | 高（アプリケーション状態回復のため） |
| リトライ | 該当なし |

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

`hasFatalError` フラグは各ブラウザタブのクライアントサイドでローカルに管理される。リロードは当該タブでのみ実行される。

## 通知テンプレート

### フラグ状態

| 項目 | 内容 |
|-----|------|
| フラグ名 | `hasFatalError` |
| 型 | `boolean` |
| 初期値 | `false` |
| エクスポート | `export let hasFatalError` |

### 関連動作

```
hasFatalError === true かつ hot_update 受信 かつ (isServerSideRouteUpdate || reader.hasMoreData())
    → fullReload() 実行
```

## テンプレート変数

該当なし（内部状態フラグのため）

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| ランタイムエラー | `onRuntimeError(err, fatal=true)` | `fatal === true` | ランタイムエラー発生時にフラグ設定 |
| ビルド成功 | `hot_update` メッセージ受信 | `hasFatalError && (isServerSideRouteUpdate \|\| reader.hasMoreData())` | 更新内容がある場合にリロード実行 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| `fatal === false` | 非致命的エラーの場合はフラグを設定しない |
| 更新なし | `hot_update` で更新内容がない場合はリロードしない |

## 処理フロー

### フラグ設定とリロードフロー

```mermaid
flowchart TD
    A[ランタイムエラー発生] --> B{fatal === true?}
    B -->|Yes| C[hasFatalError = true]
    B -->|No| D[フラグ変更なし]
    C --> E[オーバーレイ表示]
    D --> E
    E --> F[開発者がコード修正]
    F --> G[ファイル保存]
    G --> H[DevServer ビルド]
    H --> I[hot_update メッセージ送信]
    I --> J{hasFatalError === true?}
    J -->|Yes| K{更新内容あり?}
    K -->|Yes| L[fullReload 実行]
    K -->|No| M[通常 HMR 処理]
    J -->|No| M
    L --> N[ページリロード]
    M --> O[差分更新適用]
    N --> P[hasFatalError = false リセット]
```

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

### 参照テーブル一覧

該当なし（クライアントサイドのメモリ上でフラグ管理）

### クライアントサイドデータ構造

| 変数名 | 型 | 用途 | 定義場所 |
|--------|------|------|---------|
| `hasFatalError` | `boolean` | 致命的エラー発生フラグ | `src/bake/client/overlay.ts` |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| リロード失敗 | ネットワーク障害など | ユーザーによる手動リロード |

### リトライ仕様

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

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（開発時に随時発生）

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

- この機能は開発環境でのみ使用されることを想定している
- フラグはクライアントサイドでのみ管理され、サーバーには送信されない
- 本番環境では HMR 機能自体が無効化されるべきである

## 備考

- `hasFatalError` は `let` で宣言されており、モジュール外からは読み取りのみ可能（`export let`）
- リロード後、ページが再読み込みされることでフラグは自動的に `false` にリセットされる（新しいスクリプト実行により初期値に戻る）
- `fullReload()` は `location.reload()` を呼び出す
- サーバーサイドルート更新（`isServerSideRouteUpdate`）または JavaScript モジュール更新（`reader.hasMoreData()`）がある場合にのみリロードが実行される

---

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

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

### 推奨読解順序

#### Step 1: フラグ定義を理解する

`hasFatalError` フラグの定義と初期化を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | overlay.ts | `src/bake/client/overlay.ts` | 16行目の `export let hasFatalError = false` でフラグ定義を理解する |

**読解のコツ**: `let` で宣言されているため、モジュール内部からのみ値を変更可能。外部モジュールは import して参照のみ可能。

#### Step 2: フラグ設定を理解する

ランタイムエラー発生時のフラグ設定を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | overlay.ts | `src/bake/client/overlay.ts` | 216-219行目の `onRuntimeError` 関数内でのフラグ設定を理解する |
| 2-2 | hmr-runtime-client.ts | `src/bake/hmr-runtime-client.ts` | 249行目で `onRuntimeError(value, true, false)` と呼び出される |

**主要処理フロー**:
1. **216行目**: `onRuntimeError(err, fatal = false, async = false)` 関数定義
2. **218-219行目**: `if (fatal) { hasFatalError = true; }` でフラグ設定

#### Step 3: フラグ参照とリロード実行を理解する

`hot_update` ハンドラでのフラグ参照とリロード実行を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | hmr-runtime-client.ts | `src/bake/hmr-runtime-client.ts` | 6行目で `hasFatalError` を import |
| 3-2 | hmr-runtime-client.ts | `src/bake/hmr-runtime-client.ts` | 170-173行目でフラグ参照とリロード判定 |

**主要処理フロー**:
- **6行目**: `import { hasFatalError, ... } from "./client/overlay";`
- **170行目**: `if (hasFatalError && (isServerSideRouteUpdate || reader.hasMoreData()))`
- **171-173行目**: `fullReload(); return;`

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

```
window.addEventListener('error')
    │
    └─ onRuntimeError(value, fatal=true, async=false)
           │
           └─ if (fatal) hasFatalError = true
                  │
                  ▼
           [開発者がコード修正・保存]
                  │
                  ▼
           DevServer がビルド実行
                  │
                  ▼
handlers[MessageId.hot_update]
    │
    ├─ サーバーサイドルート更新解析
    │
    ├─ if (hasFatalError && ...)
    │      │
    │      └─ fullReload()
    │             │
    │             └─ location.reload()
    │
    └─ [リロードされなければ通常 HMR 処理]
```

### データフロー図

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

ランタイム
エラー発生 ─────────▶ onRuntimeError(fatal=true)
                              │
                              ▼
                     hasFatalError = true
                              │
                              ▼
                    [開発者がコード修正]
                              │
                              ▼
                    DevServer ビルド
                              │
                              ▼
                    hot_update メッセージ
                              │
                              ▼
                    hasFatalError チェック
                              │
                    ┌─────────┴─────────┐
                    ▼                   ▼
            [true & 更新あり]     [false または更新なし]
                    │                   │
                    ▼                   ▼
            fullReload() ──────▶   通常 HMR 処理
                    │
                    ▼
            location.reload()
                    │
                    ▼
            ページ再読み込み
            (hasFatalError リセット)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| overlay.ts | `src/bake/client/overlay.ts` | ソース | `hasFatalError` フラグ定義、`onRuntimeError` 関数 |
| hmr-runtime-client.ts | `src/bake/hmr-runtime-client.ts` | ソース | フラグ import、`hot_update` ハンドラでの参照とリロード判定 |
| hmr-module.ts | `src/bake/hmr-module.ts` | ソース | `fullReload` 関数定義 |
