# 通知設計書 42-エラー状態リクエスト通知

## 概要

本ドキュメントは、Next.jsの開発サーバーにおけるエラー状態リクエスト通知の設計について記述する。MCP（Model Context Protocol）等の外部ツールからエラー状態の問い合わせがあった際に、サーバーがブラウザへWebSocket経由でHMRメッセージ（`REQUEST_CURRENT_ERROR_STATE`）を転送し、ブラウザ側のDev Overlayの現在のエラー状態を収集する仕組みを定義する。

### 本通知の処理概要

エラー状態リクエスト通知は、MCPツール（get_errors）がNext.js開発サーバーを通じてブラウザに現在のエラー状態を問い合わせるためのHMR通知メッセージである。サーバーはリクエストIDを生成し、`REQUEST_CURRENT_ERROR_STATE`メッセージをWebSocket経由で全接続ブラウザに送信する。ブラウザはDev Overlayの`OverlayState`を取得し、`MCP_ERROR_STATE_RESPONSE`メッセージとしてサーバーに返送する。サーバーは全ブラウザセッションからの応答を集約し、ソースマップ処理を行った上でMCPクライアントに結果を返す。

**業務上の目的・背景**：AI支援開発ツール（Claude Code等）がNext.jsアプリケーションの開発中にブラウザ上で発生しているエラーを取得するために必要な通知である。MCPプロトコルを通じて外部ツールが開発サーバーのエラー状態をプログラマティックに取得することで、開発者がブラウザを直接確認しなくてもエラーの診断・修正が可能になる。

**通知の送信タイミング**：MCPクライアントが`get_errors`ツールを呼び出したタイミングで発生する。サーバーは接続中のブラウザセッション数を確認し、少なくとも1つの接続がある場合にのみメッセージを送信する。接続がない場合はエラーメッセージを返す。

**通知の受信者**：WebSocket経由で開発サーバーに接続されているすべてのブラウザセッション。各ブラウザセッションが個別に応答を返す。

**通知内容の概要**：メッセージには`type`（`requestCurrentErrorState`）と一意の`requestId`（`mcp-requestCurrentErrorState-{nanoid}`形式）が含まれる。ブラウザはこのリクエストIDに対応する応答として、`OverlayState`（ビルドエラー、ランタイムエラー、リフレッシュ状態など）を返す。

**期待されるアクション**：ブラウザはリクエストを受信すると、現在のDev Overlayの状態（`getSerializedOverlayState()`）を取得し、`MCP_ERROR_STATE_RESPONSE`イベントとしてWebSocket経由でサーバーに応答を返す。サーバーは応答を受信し、ソースマップ処理後にMCPクライアントに結果を返却する。

## 通知種別

WebSocket HMRメッセージ（開発サーバー → ブラウザ、JSON形式）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（WebSocket HMR経由、リクエスト-レスポンスパターン） |
| 優先度 | 中（開発支援用途） |
| リトライ | 無（タイムアウト5秒後に部分的な応答を返す or エラー） |

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

開発サーバーに現在WebSocket接続されているすべてのブラウザセッションにブロードキャストする。`getActiveConnectionCount()`で接続数を取得し、0の場合はメッセージを送信せずにエラーメッセージを返す。接続がある場合は`sendHmrMessage()`を通じて全クライアントに送信する。

## 通知テンプレート

### メール通知の場合

本通知はメール通知ではない。WebSocket HMRメッセージである。

### 本文テンプレート

```json
{
  "type": "requestCurrentErrorState",
  "requestId": "mcp-requestCurrentErrorState-{nanoid}"
}
```

### 添付ファイル

該当なし。

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| type | メッセージタイプ | HMR_MESSAGE_SENT_TO_BROWSER.REQUEST_CURRENT_ERROR_STATE | Yes |
| requestId | リクエスト識別子 | nanoid()による自動生成（`mcp-requestCurrentErrorState-{id}`形式） | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| API | MCPクライアントが`get_errors`ツールを呼び出し | ブラウザ接続数 > 0 | MCPプロトコル経由のリクエスト |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| ブラウザ接続なし | `getActiveConnectionCount() === 0`の場合、メッセージ送信をスキップしエラーを返却 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[MCPクライアントがget_errorsを呼び出し] --> B[接続数チェック]
    B -->|接続なし| C[エラーメッセージ返却]
    B -->|接続あり| D[requestId生成 - nanoid]
    D --> E[createBrowserRequest実行]
    E --> F[REQUEST_CURRENT_ERROR_STATE HMRメッセージ送信]
    F --> G[ブラウザがgetSerializedOverlayState取得]
    G --> H[MCP_ERROR_STATE_RESPONSE送信]
    H --> I[handleErrorStateResponse処理]
    I --> J{全セッション応答受信?}
    J -->|Yes| K[応答集約]
    J -->|タイムアウト| L[部分応答集約]
    K --> M[formatErrors処理]
    L --> M
    M --> N[MCPクライアントへJSON返却]
    C --> O[終了]
    N --> O
```

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

### 参照テーブル一覧

該当なし。本通知はメモリ内の状態管理のみで動作する。

### 更新テーブル一覧

該当なし。

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 接続なしエラー | ブラウザセッションが0件 | エラーメッセージ「No browser sessions connected...」をMCPに返却 |
| タイムアウト | 5秒以内にブラウザから応答がない | 部分的な応答があればそれを返す、なければタイムアウトエラー |
| 一般エラー | その他の例外 | error.messageをJSON形式でMCPに返却 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A（タイムアウト時は部分応答を返す） |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし（MCPリクエスト頻度に依存） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし。開発サーバーが稼働中であればいつでも利用可能。

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

- 本通知は開発環境でのみ動作し、本番環境では利用不可
- MCPプロトコル経由でのアクセスのみを想定し、認証はMCPサーバーの接続管理に依存
- エラー情報にはソースコードのパスやスタックトレースが含まれるため、開発環境限定で使用すること
- `requestId`にnanoidを使用して一意性を確保し、リクエストの混同を防止
- テレメトリトラッキング（`mcpTelemetryTracker.recordToolCall`）が行われる

## 備考

- `DEFAULT_BROWSER_REQUEST_TIMEOUT_MS`は5000ms（5秒）に設定されている
- 複数のブラウザセッションが接続されている場合、すべてのセッションから応答を収集する
- App Routerのhot-reloaderのみが`REQUEST_CURRENT_ERROR_STATE`を処理する（Pages Routerでは未対応）
- `NextInstanceErrorState`（next.configバリデーションエラー等）も併せて返却される
- ブラウザ側の応答には`window.location.href`が含まれ、ルートごとのエラー状態として管理される

---

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

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

### 推奨読解順序

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

HMRメッセージの型定義とOverlayStateの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | hot-reloader-types.ts | `packages/next/src/server/dev/hot-reloader-types.ts` | `REQUEST_CURRENT_ERROR_STATE`の定義（行38）、`RequestCurrentErrorStateMessage`インターフェース（行166-169） |
| 1-2 | shared.ts | `packages/next/src/next-devtools/dev-overlay/shared.ts` | `OverlayState`インターフェース（行44-73）、エラー状態の構造 |

**読解のコツ**: `HMR_MESSAGE_SENT_TO_BROWSER`はconst enumとして定義されており、JSONメッセージとバイナリメッセージの両方を含む。`REQUEST_CURRENT_ERROR_STATE`はJSONメッセージカテゴリに属する。

#### Step 2: エントリーポイントを理解する（サーバー側）

MCPツールの`get_errors`登録とリクエスト処理の起点を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | get-errors.ts | `packages/next/src/server/mcp/tools/get-errors.ts` | `registerGetErrorsTool()`（行31-125）、`createBrowserRequest`呼び出し（行63-68） |

**主要処理フロー**:
1. **行43-44**: MCPリクエスト受信、テレメトリ記録
2. **行48-61**: 接続数チェック（0の場合はエラー返却）
3. **行63-68**: `createBrowserRequest`でブラウザにリクエスト送信
4. **行72-77**: 応答を`routesErrorState` Mapに集約
5. **行98-101**: `formatErrors`でフォーマット処理

#### Step 3: ブラウザ通信基盤を理解する

リクエスト-レスポンスパターンの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | browser-communication.ts | `packages/next/src/server/mcp/tools/utils/browser-communication.ts` | `createBrowserRequest()`（行30-75）、`handleBrowserPageResponse()`（行77-97） |

**主要処理フロー**:
- **行41**: requestId生成（`mcp-{messageType}-{nanoid}`形式）
- **行45-57**: タイムアウト処理（5秒）
- **行69-72**: HMRメッセージ送信
- **行88-95**: 応答受信と完了判定

#### Step 4: ブラウザ側の応答処理を理解する

ブラウザ側でのメッセージ受信と応答送信を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | hot-reloader-app.tsx | `packages/next/src/client/dev/hot-reloader/app/hot-reloader-app.tsx` | `REQUEST_CURRENT_ERROR_STATE`ハンドラ（行488-497） |

**主要処理フロー**:
- **行489**: `getSerializedOverlayState()`でエラー状態取得
- **行490-495**: 応答メッセージ構築（requestId, errorState, url）
- **行496**: `sendMessage()`でサーバーに応答送信

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

```
MCPクライアント (get_errors呼び出し)
    │
    ├─ registerGetErrorsTool() [get-errors.ts:31]
    │      ├─ mcpTelemetryTracker.recordToolCall() [get-errors.ts:45]
    │      ├─ getActiveConnectionCount() [get-errors.ts:48]
    │      ├─ createBrowserRequest() [browser-communication.ts:30]
    │      │      ├─ nanoid() → requestId生成 [browser-communication.ts:41]
    │      │      ├─ pendingRequests.set() [browser-communication.ts:59]
    │      │      └─ sendHmrMessage() → WebSocket送信 [browser-communication.ts:69]
    │      │
    │      │  [ブラウザ側]
    │      │  └─ hot-reloader-app.tsx ハンドラ [行488-497]
    │      │         ├─ getSerializedOverlayState()
    │      │         └─ sendMessage() → MCP_ERROR_STATE_RESPONSE
    │      │
    │      ├─ handleErrorStateResponse() [get-errors.ts:130]
    │      │      └─ handleBrowserPageResponse() [browser-communication.ts:77]
    │      │
    │      └─ formatErrors() [get-errors.ts:98]
    │
    └─ MCPクライアントへJSON応答
```

### データフロー図

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

MCPクライアント ──────▶ get_errors ツール ──────▶ requestId生成
                                                      │
                                                      ▼
                        WebSocket HMR ◀───── REQUEST_CURRENT_ERROR_STATE
                              │
                              ▼
                      ブラウザ Dev Overlay
                     getSerializedOverlayState()
                              │
                              ▼
                    MCP_ERROR_STATE_RESPONSE ──────▶ サーバー集約
                                                      │
                                                      ├─ formatErrors()
                                                      ├─ ソースマップ処理
                                                      │
                                                      ▼
                                               MCPクライアントへ
                                               JSON応答返却
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| get-errors.ts | `packages/next/src/server/mcp/tools/get-errors.ts` | ソース | MCPツール登録、エラー状態取得メイン処理 |
| browser-communication.ts | `packages/next/src/server/mcp/tools/utils/browser-communication.ts` | ソース | ブラウザ通信基盤（リクエスト-レスポンスパターン） |
| hot-reloader-types.ts | `packages/next/src/server/dev/hot-reloader-types.ts` | ソース | HMRメッセージ型定義 |
| shared.ts | `packages/next/src/next-devtools/dev-overlay/shared.ts` | ソース | OverlayState型定義、エラー状態管理 |
| hot-reloader-app.tsx | `packages/next/src/client/dev/hot-reloader/app/hot-reloader-app.tsx` | ソース | ブラウザ側メッセージハンドラ |
| format-errors.ts | `packages/next/src/server/mcp/tools/utils/format-errors.ts` | ソース | エラーフォーマット処理 |
| next-instance-error-state.ts | `packages/next/src/server/mcp/tools/next-instance-error-state.ts` | ソース | Next.jsインスタンスエラー状態管理 |
