# 通知設計書 19-サーバーエラー通知

## 概要

本ドキュメントは、Next.js開発サーバーにおける「サーバーエラー通知」（HMR_MESSAGE_SENT_TO_BROWSER.SERVER_ERROR）の設計を記述する。この通知は、サーバーサイドでエラーが発生した際にブラウザへWebSocket経由で通知し、エラーオーバーレイを表示させる。

### 本通知の処理概要

この通知は、サーバーサイドで致命的なエラー（シンタックスエラー、設定エラー、デコードエラーなど）が発生した場合に、開発サーバーからブラウザへHMRメッセージとして送信される。

**業務上の目的・背景**：開発中にサーバーサイドコードでエラーが発生した場合、ブラウザ上でそのエラーを可視化する必要がある。特にWebpackモードでは、特定のページに対するサーバーサイドエラー（デコードエラー等）が発生した際に、そのエラー情報をJSON化してブラウザに送信することで、開発者がエラーの詳細（メッセージ、スタックトレース）を確認できる。

**通知の送信タイミング**：(1) Webpackモードでのページコンパイルエラー時。(2) ページリクエスト処理中にDecodeError等が発生した場合。

**通知の受信者**：WebSocket接続を確立しているブラウザクライアント。

**通知内容の概要**：メッセージタイプ`serverError`と、JSON文字列化されたエラーオブジェクト（message, stack）が含まれる。

**期待されるアクション**：ブラウザはerrorJSONを解析してErrorオブジェクトを再構築し、エラーオーバーレイに表示する。

## 通知種別

WebSocket（アプリ内通知） - ブラウザへのHMRメッセージ

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（WebSocket push） |
| 優先度 | 高 |
| リトライ | 無 |

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

Webpackモードでは`WebpackHotMiddleware.publish()`を通じて全クライアントに送信される。

## 通知テンプレート

### メール通知の場合

該当なし

### 本文テンプレート

```json
{
  "type": "serverError",
  "errorJSON": "{\"message\":\"Error message\",\"stack\":\"Error stack trace\"}"
}
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| type | メッセージタイプ識別子 | HMR_MESSAGE_SENT_TO_BROWSER.SERVER_ERROR定数 (`serverError`) | Yes |
| errorJSON | JSON文字列化されたエラーオブジェクト | JSON.stringify({ message: error.message, stack: error.stack }) | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| サーバーエラー | ページリクエスト処理中のDecodeError | DecodeError型のエラーが発生した場合 | hot-reloader-webpack.ts 内の send()呼び出し |
| サーバーエラー | ページコンパイル時のサーバーサイドエラー | Webpackサーバーコンパイラでエラーが発生した場合 | hot-reloader-webpack.ts 内のsetImmediate send()呼び出し |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| Turbopackモード | Turbopackモードでは通常BUILTメッセージのerrors配列でエラーを伝達するため、SERVER_ERRORメッセージは使用されにくい |
| closed状態 | WebSocketが閉じている場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[サーバーサイドエラー発生] --> B{エラー種別}
    B -->|DecodeError| C[エラー情報をJSON.stringify]
    B -->|コンパイルエラー| D[エラー情報をJSON.stringify]
    C --> E[ServerErrorMessage生成]
    D --> E
    E --> F[WebSocket経由で送信]
    F --> G[クライアント側処理]
    G --> H[errorJSONをJSON.parse]
    H --> I[Errorオブジェクト再構築]
    I --> J[handleErrors - エラーオーバーレイ表示]
```

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

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| errorJSONパース失敗 | 不正なJSON文字列が送信された場合 | クライアント側でJSON.parseが例外をスローし、デフォルトのエラーハンドリングに委ねる |

### リトライ仕様

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

## 配信設定

### レート制限

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

### 配信時間帯

開発サーバー稼働中は常時送信可能

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

- 開発環境専用
- errorJSONにはファイルパス、ソースコード断片、スタックトレースが含まれる
- 本番環境では送信されないため、セキュリティリスクは限定的

## 備考

- Pages Router（page-bootstrap.ts 31-36行目）では、SERVER_ERRORを受信するとerrorJSONをパースしてErrorオブジェクトを生成し、`throw error`で例外を投げる（エラーバウンダリでキャッチされる）
- App Router（hot-reloader-app.tsx 454-462行目）では、同様にErrorオブジェクトを再構築し、`handleErrors([error])`でエラーオーバーレイを表示する
- Pages Router（hot-reloader-pages.ts 349-357行目）でも同様にhandleErrors処理が行われる
- Turbopackモードでは、サーバーエラーは主にBUILTメッセージのerrors配列で伝達されるため、SERVER_ERRORメッセージの使用頻度は低い

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | hot-reloader-types.ts | `packages/next/src/server/dev/hot-reloader-types.ts` | 95-98行目: ServerErrorMessage型定義。typeフィールドとerrorJSONフィールド |
| 1-2 | hot-reloader-types.ts | `packages/next/src/server/dev/hot-reloader-types.ts` | 30行目: SERVER_ERROR = `serverError` |

#### Step 2: サーバー側送信ロジック

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | hot-reloader-webpack.ts | `packages/next/src/server/dev/hot-reloader-webpack.ts` | send()メソッド内でSERVER_ERRORメッセージを送信する箇所 |

**主要処理フロー**:
1. ページリクエスト処理中にDecodeError等のエラーが発生
2. エラーオブジェクトの`message`と`stack`をJSON.stringify()でシリアライズ
3. ServerErrorMessageを構築し、WebSocket経由で送信

#### Step 3: クライアント側受信処理

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | page-bootstrap.ts | `packages/next/src/client/page-bootstrap.ts` | 31-36行目: SERVER_ERROR受信時にerrorJSONをパースしてthrow |
| 3-2 | hot-reloader-app.tsx | `packages/next/src/client/dev/hot-reloader/app/hot-reloader-app.tsx` | 454-462行目: App RouterでのSERVER_ERROR処理。Errorオブジェクト再構築しhandleErrors |
| 3-3 | hot-reloader-pages.ts | `packages/next/src/client/dev/hot-reloader/pages/hot-reloader-pages.ts` | 349-357行目: Pages RouterでのSERVER_ERROR処理 |

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

```
[サーバー側]
hot-reloader-webpack.ts: send() / ページリクエスト処理
    |
    +-- エラー発生
            |
            +-- JSON.stringify({ message, stack })
            +-- publish({ type: SERVER_ERROR, errorJSON })
                    +-- 全クライアントにWebSocket送信

[クライアント側 - page-bootstrap.ts]
addMessageListener()
    |
    +-- case SERVER_ERROR:
            +-- JSON.parse(errorJSON) -> errorObject
            +-- new Error(errorObject.message)
            +-- error.stack = errorObject.stack
            +-- throw error

[クライアント側 - hot-reloader-app.tsx]
processMessage()
    |
    +-- case SERVER_ERROR:
            +-- JSON.parse(errorJSON) -> errorObject
            +-- new Error(errorObject.message)
            +-- error.stack = errorObject.stack
            +-- handleErrors([error])
                    +-- dispatcher.onBuildError(formatted.errors[0])
```

### データフロー図

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

サーバーエラー            サーバー側                        ブラウザ
(DecodeError等)    -----> JSON.stringify(error)
                          |
                          v
                    ServerErrorMessage生成
                    { type: "serverError",
                      errorJSON: "{...}" }
                          |
                          v
                    WebSocket JSON送信 ----------> processMessage()
                                                   |
                                                   v
                                            JSON.parse(errorJSON)
                                            Errorオブジェクト再構築
                                                   |
                                                   v
                                            エラーオーバーレイ表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| hot-reloader-types.ts | `packages/next/src/server/dev/hot-reloader-types.ts` | ソース | ServerErrorMessage型定義 |
| hot-reloader-webpack.ts | `packages/next/src/server/dev/hot-reloader-webpack.ts` | ソース | Webpackモードでのサーバーエラー送信 |
| page-bootstrap.ts | `packages/next/src/client/page-bootstrap.ts` | ソース | Pages Routerでのthrowによるエラー伝播 |
| hot-reloader-app.tsx | `packages/next/src/client/dev/hot-reloader/app/hot-reloader-app.tsx` | ソース | App RouterでのSERVER_ERROR処理 |
| hot-reloader-pages.ts | `packages/next/src/client/dev/hot-reloader/pages/hot-reloader-pages.ts` | ソース | Pages RouterでのSERVER_ERROR処理 |
