# 画面設計書 104-404エラー画面

## 概要

本ドキュメントは、Ghost CMS管理画面（Ghost Admin）の404エラー画面の設計を定義するものである。この画面は存在しないURLにアクセスした際に表示されるエラーページである。

### 本画面の処理概要

404エラー画面は、Ghost管理画面内で存在しないルートにアクセスした際に表示されるエラーページである。ユーザーに対してページが見つからないことを通知し、正しいナビゲーションへ誘導する役割を持つ。

**業務上の目的・背景**：管理画面のURLを直接入力したり、古いブックマークからアクセスしたりした場合、存在しないページにアクセスすることがある。このエラー画面は、ユーザーに現在の状況を明確に伝え、混乱を防ぐために必要である。また、一部の古いURL（editor-beta）からのアクセスは新しいルートへ自動的にリダイレクトする機能も持ち、後方互換性を確保している。

**画面へのアクセス方法**：この画面は管理画面（/ghost/）配下で定義されていないパスにアクセスした際に自動的に表示される。意図的にアクセスする画面ではなく、エラー状態を表示するための画面である。

**主要な操作・処理内容**：
1. 旧ルートのリダイレクト - editor-betaからlexical-editorへの自動リダイレクト
2. エラーモデルの生成 - ステータス404のエラーオブジェクトを作成
3. エラー情報の表示 - エラーコードとメッセージを表示
4. スタックトレース表示（開発時） - 詳細なエラー情報の表示

**画面遷移**：
- 遷移元: 任意のページ（不正なURLへのアクセス）
- 遷移先:
  - editor-betaからのアクセス時はlexical-editorへリダイレクト
  - その他は特定の遷移先なし（ユーザーが手動でナビゲーション）

**権限による表示制御**：この画面は認証済みユーザーのみがアクセス可能な管理画面の一部である。認証されていない場合は先にサインイン画面へリダイレクトされる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 76 | Ghost Admin | 主機能 | ページが見つからない場合のエラー表示 |
| 88 | 認証 | 補助機能 | 認証済みユーザーのみアクセス可能 |

## 画面種別

エラー表示

## URL/ルーティング

- ルート定義: `error404` (path: `/*path`)
- 実際のURL: `/ghost/{存在しないパス}`

## 入出力項目

### 入力項目（なし）

この画面はユーザー入力を受け付けない。

### パラメータ（ルートパラメータ）

| 項目名 | パラメータ名 | 型 | 説明 |
|--------|-------------|-----|------|
| パス | path | string | アクセスされた不正なパス（ワイルドカードマッチ） |

## 表示項目

| 項目名 | 表示条件 | 説明 |
|--------|----------|------|
| エラーコード | code > 0の場合 | HTTPステータスコード（通常404） |
| 区切り文字 | codeが存在する場合 | "|" |
| エラーメッセージ | 常時 | "Page not found" または適切なエラーメッセージ |
| スタックトレース | stack が存在する場合 | エラーのスタックトレース情報（開発環境用） |

### スタックトレース表示項目

| 項目名 | 表示条件 | 説明 |
|--------|----------|------|
| Stack Trace見出し | stack存在時 | h3タグ |
| エラーメッセージ | stack存在時 | strongタグで強調表示 |
| 関数名 | item.function存在時 | emタグで表示 |
| ファイル位置 | 各スタック項目 | item.at の値をspanタグで表示 |

## イベント仕様

### 1-ルートアクセス（beforeModel）

**トリガー**: error404ルートへの遷移

**処理フロー**:
1. transition.to.params.pathを確認
2. パスが'editor-beta'で始まる場合:
   - パスを分割してtype, postIdを取得
   - postIdが存在すれば'lexical-editor.edit'へ、なければ'lexical-editor.new'へリダイレクト
3. その他の場合は処理を続行

### 2-モデル生成（model）

**トリガー**: beforeModelの後

**処理フロー**:
1. `{ status: 404 }` オブジェクトを返す
2. このオブジェクトがErrorControllerのmodelプロパティに設定される

### 3-エラー表示（コントローラー処理）

**トリガー**: テンプレートレンダリング

**処理フロー**:
1. ErrorControllerのcodeゲッターが呼び出される
   - error.status > 200 なら error.status を返す
   - それ以外は 500 を返す
2. ErrorControllerのmessageゲッターが呼び出される
   - code === 404 なら 'Page not found' を返す
   - それ以外は error.statusText または 'Internal Server Error' を返す

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| - | - | - | この画面ではデータベース操作は発生しない |

エラー表示のみを行う画面であり、データベースへのアクセスは行わない。

## メッセージ仕様

| メッセージID | 種別 | メッセージ | 表示条件 |
|-------------|------|-----------|----------|
| MSG-001 | エラー | Page not found | code === 404 の場合 |
| MSG-002 | エラー | Internal Server Error | statusTextが'error'または未設定の場合 |
| MSG-003 | エラー | {statusText} | その他のエラーの場合 |

## 例外処理

| 例外状況 | 処理内容 | 表示メッセージ |
|---------|---------|---------------|
| 404エラー | 404コードと「Page not found」を表示 | Page not found |
| その他のエラー | 適切なステータスコードとメッセージを表示 | {statusText} または Internal Server Error |

## 備考

- このルートはワイルドカードマッチ（`/*path`）を使用しており、他のルートにマッチしないすべてのパスがキャッチされる
- `controllerName = 'error'`と`templateName = 'error'`の設定により、ErrorControllerとerror.hbsテンプレートを使用する
- `buildRouteInfoMetadata()`でタイトルトークン'Error'が設定され、ブラウザタブに反映される
- editor-betaからのリダイレクトは後方互換性のために実装されている
- スタックトレースは通常、開発環境でのみ表示される

---

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

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

### 推奨読解順序

#### Step 1: ルーティングを理解する

error404ルートの定義と遷移の仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | router.js | `ghost/admin/app/router.js` | 91行目でerror404ルートがワイルドカードパスとして定義されていることを確認 |

**読解のコツ**: Ember.jsのルーター定義で、`/*path`パターンは他のルートにマッチしないすべてのパスをキャッチするワイルドカードルートである。

#### Step 2: ルートクラスを理解する

Error404Routeの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | error404.js | `ghost/admin/app/routes/error404.js` | controllerName, templateName, beforeModel, model, buildRouteInfoMetadataの各メソッド |

**主要処理フロー**:
- **5-6行目**: controllerNameとtemplateNameで使用するコントローラーとテンプレートを指定
- **10-24行目**: beforeModelでeditor-betaからのリダイレクト処理
- **26-29行目**: modelで`{ status: 404 }`を返す
- **31-35行目**: buildRouteInfoMetadataでタイトル設定

#### Step 3: コントローラーを理解する

ErrorControllerの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | error.js | `ghost/admin/app/controllers/error.js` | error, code, messageの各ゲッター |

**主要処理フロー**:
- **4行目**: stackプロパティのデフォルト値false
- **6-8行目**: errorゲッターでmodelを返す
- **10-12行目**: codeゲッターでHTTPステータスコードを決定
- **14-20行目**: messageゲッターでエラーメッセージを決定

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

error.hbsテンプレートの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | error.hbs | `ghost/admin/app/templates/error.hbs` | エラー情報の表示構造、スタックトレースの条件付き表示 |

**主要処理フロー**:
- **1-15行目**: メインのエラー表示（コード、メッセージ）
- **17-31行目**: スタックトレースの条件付き表示（開発環境用）

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

```
router.js (route定義)
    |
    +-- this.route('error404', {path: '/*path'})
            |
            v
Error404Route (error404.js)
    |
    +-- beforeModel(transition)
    |       |
    |       +-- [editor-beta] router.transitionTo('lexical-editor.*')
    |
    +-- model()
    |       |
    |       +-- return { status: 404 }
    |
    +-- buildRouteInfoMetadata()
            |
            +-- return { titleToken: 'Error' }
            |
            v
ErrorController (error.js)
    |
    +-- get error() --> this.model
    +-- get code() --> 404 or 500
    +-- get message() --> 'Page not found' or ...
            |
            v
error.hbs (テンプレート)
    |
    +-- {{this.code}}
    +-- {{this.message}}
    +-- {{#if this.stack}} ... {{/if}}
```

### データフロー図

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

/ghost/invalid-path ─────▶ router.js ─────────────────────▶ error404ルートにマッチ
                                |
                                v
                          Error404Route.beforeModel()
                                |
                                +── [editor-beta判定]
                                |       |
                                |       +─[Yes]─▶ lexical-editorへリダイレクト
                                |       |
                                |       +─[No]──▶ 続行
                                |
                                v
                          Error404Route.model()
                                |
                                +── { status: 404 }
                                        |
                                        v
                          ErrorController
                                |
                                +── code: 404
                                +── message: 'Page not found'
                                        |
                                        v
                          error.hbs
                                |
                                v
                          404 | Page not found
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| router.js | `ghost/admin/app/router.js` | ソース | ルート定義（91行目にerror404） |
| error404.js | `ghost/admin/app/routes/error404.js` | ソース | Error404ルートクラス |
| error.js | `ghost/admin/app/controllers/error.js` | ソース | エラーコントローラー |
| error.hbs | `ghost/admin/app/templates/error.hbs` | テンプレート | エラー表示テンプレート |
