# 画面設計書 30-汎用エラーページ

## 概要

本ドキュメントは、Shopware 6 Storefrontの汎用エラーページの画面設計書である。404以外のエラー発生時に表示される汎用的なエラー画面について記載する。

### 本画面の処理概要

汎用エラーページは、404以外のHTTPエラー（500など）やシステム例外が発生した場合に表示されるエラー画面である。

**業務上の目的・背景**：ECサイト運用において、予期せぬシステムエラーが発生した場合でも、ユーザーに適切なエラーメッセージを表示し、ユーザー体験の低下を最小限に抑える。フラッシュメッセージによるエラー通知と、ベーステンプレートを継承した統一感のあるエラー画面を提供する。

**画面へのアクセス方法**：
- システムエラー発生時（自動表示）
- 未処理の例外発生時

**主要な操作・処理内容**：
1. エラーメッセージの表示（フラッシュバッグ経由）
2. ヘッダー・フッターを含む統一されたエラー画面の表示
3. HTTPステータスコードの適切な設定

**画面遷移**：
- 遷移元：任意のページ（エラー発生時）
- 遷移先：ホームページ（ナビゲーション経由）

**権限による表示制御**：
- 特になし（全ユーザーに表示）

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 67 | エラーページ | 主機能 | システムエラー時のエラー表示（ErrorController::error） |

## 画面種別

エラー

## URL/ルーティング

| ルート名 | URL | HTTPメソッド | 説明 |
|----------|-----|--------------|------|
| なし | 任意（エラー発生時） | - | Symfonyのエラーハンドリング機構から呼び出し |

※ ErrorControllerはルートを持たず、例外発生時にSymfonyのエラーハンドリング機構から呼び出される

## 入出力項目

### 入力項目

| 項目名 | パラメータ名 | 型 | 必須 | 説明 |
|--------|-------------|-----|------|------|
| 例外 | exception | \Throwable | 必須 | 発生した例外 |
| リクエスト | request | Request | 必須 | HTTPリクエスト |
| コンテキスト | context | SalesChannelContext | 必須 | 販売チャネルコンテキスト |

### 出力項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| page | ErrorTemplateStruct | エラーテンプレート情報 |
| exception | \Throwable | 例外情報 |

## 表示項目

### エラーページ

| 項目名 | データソース | 説明 |
|--------|-------------|------|
| ヘッダー | base.html.twig | 共通ヘッダー |
| フラッシュメッセージ | session.flashBag | エラーメッセージ |
| フッター | base.html.twig | 共通フッター |

### フラッシュメッセージ

| 項目名 | データソース | 説明 |
|--------|-------------|------|
| エラーメッセージ | error.message-default | デフォルトエラーメッセージ |
| 警告メッセージ | flashBag.warning | 警告タイプのメッセージ |
| エラーメッセージ | flashBag.error | エラータイプのメッセージ |
| 危険メッセージ | flashBag.danger | 危険タイプのメッセージ |

## イベント仕様

### 1-エラー処理

1. 例外のステータスコードを判定
2. 404以外の場合、フラッシュバッグにデフォルトエラーメッセージを追加
3. ErrorTemplateResolverでテンプレートを解決
4. error-std.html.twig（または専用テンプレート）をレンダリング
5. HttpExceptionの場合、ステータスコードを設定
6. フラッシュバッグをクリア

### 2-テンプレート解決ロジック

ErrorTemplateResolverは以下のロジックでテンプレートを決定：
1. AJAXリクエストの場合は `error-ajax` プレフィックス
2. 通常リクエストの場合は `error` プレフィックス
3. ステータスコード専用テンプレート（error-{code}.html.twig）が存在する場合はそれを使用
4. 存在しない場合は `error-std.html.twig` を使用

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

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

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

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| error.message-default | フラッシュ | エラーが発生しました | 404以外のエラー時 |

## 例外処理

| 例外 | 原因 | 処理内容 |
|------|------|----------|
| HttpException | HTTPエラー | ステータスコードを設定してエラーページ表示 |
| \Throwable | 任意の例外 | 500エラーとしてエラーページ表示 |
| \Exception (レンダリング中) | テンプレートエラー | index.html.twigでフォールバック表示 |

## 備考

- HTTPステータスコードは例外から取得（HttpExceptionの場合）
- 404以外のエラーの場合、フラッシュバッグにデフォルトエラーメッセージを追加
- フラッシュバッグは表示後にクリア
- _page.html.twigを継承し、base.html.twigを利用
- AJAXリクエストの場合はerror-ajax-*.html.twigを使用
- テンプレートレンダリングに失敗した場合はindex.html.twigでフォールバック

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ErrorTemplateStruct.php | `src/Storefront/Framework/Twig/ErrorTemplateStruct.php` | templateName, arguments |

**読解のコツ**: ErrorTemplateStructはテンプレート名とテンプレートに渡す引数（例外情報など）を保持する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ErrorController.php | `src/Storefront/Controller/ErrorController.php` | error()メソッド |

**主要処理フロー**:
1. **35行**: error()メソッド定義（\Throwable, Request, SalesChannelContext受け取り）
2. **40-41行**: 404ステータスコードの判定
3. **43-45行**: 404以外の場合、フラッシュバッグにデフォルトエラーメッセージ追加
4. **47行**: navigationIdをリクエストに設定
5. **59行**: ErrorTemplateResolverでテンプレート解決
6. **61行**: 解決されたテンプレートでレンダリング
7. **64-66行**: HttpExceptionの場合、ステータスコード設定
8. **67-74行**: フォールバック処理（レンダリング失敗時）
9. **79-81行**: フラッシュバッグをクリア

#### Step 3: テンプレート解決を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ErrorTemplateResolver.php | `src/Storefront/Framework/Twig/ErrorTemplateResolver.php` | resolve()メソッド |

**主要処理フロー**:
- **21-46行**: resolve() - テンプレートを解決
- **25-27行**: AJAXリクエストの場合はerror-ajaxプレフィックス
- **29-33行**: ステータスコードを取得
- **35-41行**: 専用テンプレートが存在するか確認
- **40行**: 存在しない場合はerror-stdを使用

#### Step 4: テンプレートを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | error-std.html.twig | `src/Storefront/Resources/views/storefront/page/error/error-std.html.twig` | 汎用エラーテンプレート |
| 4-2 | _page.html.twig | `src/Storefront/Resources/views/storefront/page/error/_page.html.twig` | エラーページベース |
| 4-3 | index.html.twig | `src/Storefront/Resources/views/storefront/page/error/index.html.twig` | フォールバックテンプレート |

**テンプレート継承構造**:
- error-std.html.twig → _page.html.twig → base.html.twig
- _page.html.twigでフラッシュメッセージを表示（3-11行）
- base_contentブロックは空（ヘッダー・フッター・フラッシュメッセージのみ）

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

```
Symfony ErrorHandler
    │
    └─ ErrorController::error()
           │
           ├─ is404StatusCode判定
           │
           ├─ [404以外]
           │      │
           │      └─ flashBag.add('danger', 'error.message-default')
           │
           ├─ [404でカスタムページなし、または404以外]
           │      │
           │      ├─ ErrorTemplateResolver::resolve()
           │      │      │
           │      │      ├─ [AJAXリクエスト]
           │      │      │      └─ template = 'error-ajax'
           │      │      │
           │      │      ├─ [通常リクエスト]
           │      │      │      └─ template = 'error'
           │      │      │
           │      │      ├─ [専用テンプレートあり]
           │      │      │      └─ template = 'error-{code}'
           │      │      │
           │      │      └─ [専用テンプレートなし]
           │      │             └─ template = 'error-std'
           │      │
           │      └─ renderStorefront(template)
           │
           ├─ [HttpException]
           │      │
           │      └─ setStatusCode(exception.statusCode)
           │
           ├─ [レンダリング失敗]
           │      │
           │      └─ renderStorefront('index.html.twig', fallback)
           │
           └─ flashBag.clear()
```

### データフロー図

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

\Throwable (exception)
         │
         ▼
 ErrorController::error()
         │
         ├─► is404StatusCode = exception instanceof HttpException && code === 404
         │
         ├─► [!is404StatusCode]
         │         │
         │         └─► flashBag.add('danger', 'error.message-default')
         │
         ├─► request.attributes.set('navigationId', ...)
         │
         └─► [404でカスタムページなし、または404以外]
                   │
                   ▼
              ErrorTemplateResolver::resolve()
                   │
                   ├─► isXmlHttpRequest() → 'error-ajax' / 'error'
                   │
                   ├─► getStatusCode() → code
                   │
                   ├─► twig.exists('error-{code}.html.twig')
                   │         │
                   │         ├─► [true] → 'error-{code}.html.twig'
                   │         │
                   │         └─► [false] → 'error-std.html.twig'
                   │
                   └─► ErrorTemplateStruct
                            │
                            ▼
                       renderStorefront()
                            │
                            ├─► _page.html.twig
                            │      │
                            │      ├─► base.html.twig
                            │      │
                            │      └─► flashbags表示
                            │
                            └─► Response (status=exception.statusCode)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ErrorController.php | `src/Storefront/Controller/ErrorController.php` | コントローラー | エラー処理 |
| ErrorTemplateResolver.php | `src/Storefront/Framework/Twig/ErrorTemplateResolver.php` | サービス | テンプレート解決 |
| ErrorTemplateStruct.php | `src/Storefront/Framework/Twig/ErrorTemplateStruct.php` | 構造体 | テンプレート情報 |
| error-std.html.twig | `src/Storefront/Resources/views/storefront/page/error/error-std.html.twig` | テンプレート | 汎用エラーページ |
| _page.html.twig | `src/Storefront/Resources/views/storefront/page/error/_page.html.twig` | テンプレート | エラーページベース |
| index.html.twig | `src/Storefront/Resources/views/storefront/page/error/index.html.twig` | テンプレート | フォールバック |
| base.html.twig | `src/Storefront/Resources/views/storefront/base.html.twig` | テンプレート | ベーステンプレート |
| alert.html.twig | `src/Storefront/Resources/views/storefront/utilities/alert.html.twig` | テンプレート | アラート表示 |
