# 画面設計書 10-dubスタートアップ失敗通知

## 概要

本ドキュメントは、serve-d LSPサーバーにおけるdubスタートアップ失敗通知の画面設計書である。dubの初期化に失敗しfsworkspaceにフォールバックする際にエラーメッセージを表示する。

### 本画面の処理概要

**業務上の目的・背景**：DUBはD言語の標準的なパッケージマネージャ兼ビルドシステムであり、多くのD言語プロジェクトがDUBを使用している。DUBの初期化に失敗した場合、パッケージ依存関係の解決やビルド設定の取得ができなくなるが、serve-dは完全に停止するのではなく、fsworkspace（ファイルシステムベースのワークスペース）にフォールバックして限定的な機能を提供する。本通知はユーザーにDUBの初期化失敗を知らせ、機能が制限されていることを伝えるために存在する。

**画面へのアクセス方法**：No.3 ワークスペーススタートアップの `delayedProjectActivation` 関数内で、DUBコンポーネントのアタッチまたは初期化処理が例外をスローした場合に、`proj.startupError` を通じてエラーメッセージが記録・表示される。

**主要な操作・処理内容**：
1. `delayedProjectActivation` 内で `backend.attachEager(instance, "dub")` が失敗を返す
2. またはDUB初期化中に例外が発生する
3. `proj.startupError` でワークスペースにエラーを記録
4. fsworkspace（ファイルシステムベースのワークスペース）へのフォールバックを実行
5. fsworkspaceの初期化にも失敗した場合は追加のエラーを記録

**画面遷移**：
- 遷移元：No.3 ワークスペーススタートアップ（delayedProjectActivation内でDUB初期化失敗時）
- 遷移先：なし（エラーメッセージの記録と表示のみ）

**権限による表示制御**：なし。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 81 | 翻訳・多言語対応 | 主機能 | dubの初期化失敗時にfsworkspaceへのフォールバックを伝えるエラーメッセージの翻訳を使用する |

## 画面種別

サーバー内部エラー記録 + クライアントへのエラーメッセージ表示

## URL/ルーティング

明示的なLSPメソッドではない。`delayedProjectActivation` 内部のエラーハンドリングで発生する。エラーメッセージは `Workspace.startupError` に蓄積され、クライアントに配信される。

## 入出力項目

### 入力（内部パラメータ）

| 項目名 | 型 | 必須 | 説明 |
|--------|------|------|------|
| instance.cwd | string | はい | DUB初期化を試みたワークスペースのパス |
| err | Exception | いいえ | DUB初期化時にスローされた例外（メッセージ取得用） |
| workspaceRoot | string | はい | ワークスペースルートパス |

### 出力

| 項目名 | 種別 | 説明 |
|--------|------|------|
| startupErrorNotifications | Workspace内蓄積 | ワークスペースのエラー通知テーブルにエラーメッセージを蓄積 |

## 表示項目

### エラーメッセージ

| 項目 | 内容 | 説明 |
|------|------|------|
| DUB失敗メッセージ | "Could not initialize dub for {ワークスペースパス}. Falling back to limited functionality!\n\n{例外メッセージ}" | DUB初期化失敗とフォールバックの通知 |
| fsworkspace失敗メッセージ | "Could not initialize fsworkspace for {ワークスペースパス}. See console for details!" | fsworkspaceフォールバックも失敗した場合 |

## イベント仕様

### 1-DUB初期化失敗検出

1. `delayedProjectActivation` 内で `backend.attachEager(instance, "dub", err)` を呼び出し
2. 以下のいずれかの条件でDUB初期化失敗と判定:
   - `attachEager` が `false` を返した場合
   - DUB初期化中に例外が発生した場合
3. エラーログ "Exception starting dub: ..." を出力

### 2-DUB失敗エラー記録

1. `proj.startupError(workspaceRoot, translate!"d.ext.dubFail"(instance.cwd, err ? err.msg : ""))` を呼び出し
2. `Workspace.startupErrorNotifications` テーブルにエラーメッセージを蓄積
3. 既存のエラーがある場合は改行で連結される

### 3-fsworkspaceフォールバック

1. DUB初期化失敗後、fsworkspaceコンポーネントのアタッチを試行
2. `instance.config.set("fsworkspace", "additionalPaths", getPossibleSourceRoots(workspaceRoot))` でソースパスを設定
3. `backend.attachEager(instance, "fsworkspace", err)` でfsworkspaceをアタッチ

### 4-fsworkspaceフォールバック失敗

1. fsworkspaceのアタッチも失敗した場合
2. `proj.startupError(workspaceRoot, translate!"d.ext.fsworkspaceFail"(instance.cwd))` で追加エラーを記録

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

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

| 操作（イベント） | 対象データ | 操作種別 | 概要 |
|----------------|-----------|---------|------|
| DUB失敗 | Workspace.startupErrorNotifications | 追加 | dubFailエラーメッセージを蓄積 |
| fsworkspace失敗 | Workspace.startupErrorNotifications | 追加 | fsworkspaceFailエラーメッセージを蓄積 |
| DUBコンポーネント | instance.DubComponent | デタッチ | 失敗時にDubComponentをデタッチ |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|------------|------|--------------|----------|
| d.ext.dubFail | error | "Could not initialize dub for {0}. Falling back to limited functionality!\n\n{1}" | DUB初期化失敗時 |
| d.ext.fsworkspaceFail | error | "Could not initialize fsworkspace for {0}. See console for details!" | fsworkspace初期化失敗時 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| DUB attachEager失敗 | DubComponentをデタッチし、fsworkspaceにフォールバック |
| DUB初期化中に例外発生 | エラーログ出力 + startupErrorに記録 + fsworkspaceフォールバック |
| fsworkspace attachEager失敗 | エラーログ出力 + startupErrorに追加記録 |
| neverUseDub=true | DUBの初期化を完全にスキップし、直接fsworkspaceを使用 |

## 備考

- `Workspace.startupError` メソッドはエラーメッセージを蓄積するヘルパーであり、複数のエラーが発生した場合は改行で連結される
- `d.neverUseDub` が `true` の場合、DUBの初期化は最初から行われず、直接fsworkspaceが使用される
- `disableDub` フラグは `proj.config.d.neverUseDub || !root.useDub` で決定される
- DUB初期化失敗時の `scope (failure) instance.detach!DubComponent` により、例外発生時にDubComponentのクリーンアップが保証される
- fsworkspaceへのフォールバック時は `getPossibleSourceRoots(workspaceRoot)` で `source/` または `src/` ディレクトリを推定する
- エラーメッセージの蓄積は `Workspace.startupErrorNotifications` ディクショナリで管理され、ワークスペースパスをキーとしている

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.d | `source/served/types.d` | `Workspace` 構造体（270行目〜）の `startupErrorNotifications`（274行目）と `startupError` メソッド（278行目〜294行目）を確認 |

**読解のコツ**: `startupError` メソッドは `string[string]` 型のディクショナリにエラーメッセージを蓄積する。キーはフォルダパス、値はエラーメッセージの連結文字列。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | extension.d | `source/served/extension.d` | `delayedProjectActivation` 関数内のDUB初期化ブロック（784行目〜898行目） |

**主要処理フロー**:
1. **784行目**: `disableDub = proj.config.d.neverUseDub || !root.useDub` で判定
2. **787-877行目**: DUB初期化ブロック（`!disableDub` の場合）
3. **796行目**: `backend.attachEager(instance, "dub", err)` でDUBアタッチ試行
4. **798-799行目**: `scope (failure) instance.detach!DubComponent` でクリーンアップ保証
5. **866-871行目**: 例外キャッチ - `loadedDub = false` 設定
6. **873-874行目**: 失敗ログ出力
7. **878-883行目**: fsworkspaceフォールバック開始
8. **883行目**: `proj.startupError(workspaceRoot, translate!"d.ext.dubFail"(...))` でエラー記録
9. **885-898行目**: fsworkspace初期化試行
10. **897行目**: fsworkspace失敗時の `proj.startupError(workspaceRoot, translate!"d.ext.fsworkspaceFail"(...))`

#### Step 3: startupErrorメカニズムを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | types.d | `source/served/types.d` | `Workspace.startupError` メソッド（278行目〜294行目）- エラーメッセージの蓄積ロジック（改行/スペース連結） |

#### Step 4: 翻訳メッセージを確認する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | en.txt | `views/en.txt` | 103行目: "d.ext.dubFail: Could not initialize dub for {0}. Falling back to limited functionality!\n\n{1}" |
| 4-2 | en.txt | `views/en.txt` | 92行目: "d.ext.fsworkspaceFail: Could not initialize fsworkspace for {0}. See console for details!" |

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

```
delayedProjectActivation(...)  [727行目]
    │
    ├─ [DUB初期化ブロック]  [787行目]
    │      ├─ backend.attachEager(instance, "dub")  [796行目]
    │      │      └─ scope(failure) instance.detach!DubComponent  [799行目]
    │      │
    │      ├─ [成功] → dub.validateConfiguration() → 依存関係チェック
    │      │
    │      └─ [失敗/例外]
    │             ├─ error("Exception starting dub: ", err)  [874行目]
    │             └─ loadedDub = false
    │
    ├─ [DUB失敗後のフォールバック]  [878行目]
    │      │
    │      ├─ proj.startupError(workspaceRoot, "d.ext.dubFail")  [883行目]
    │      │
    │      ├─ instance.config.set("fsworkspace", "additionalPaths", ...)  [889-890行目]
    │      │      └─ getPossibleSourceRoots(workspaceRoot)  [213行目]
    │      │
    │      └─ backend.attachEager(instance, "fsworkspace")  [891行目]
    │             │
    │             ├─ [成功] → fsworkspace利用
    │             │
    │             └─ [失敗]
    │                    └─ proj.startupError(workspaceRoot, "d.ext.fsworkspaceFail")  [897行目]
    │
    └─ [DUBロード成功時] → didLoadDubProject()  [901行目]
```

### データフロー図

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

WorkspaceD.Instance ──▶ delayedProjectActivation()     startupErrorNotifications
  .cwd                       │                            （エラーメッセージ蓄積）
RootSuggestion               ├─ DUB初期化試行
  .useDub                    │      └─ [失敗]
Configuration                │             ├─ dubFailメッセージ記録
  .d.neverUseDub             │             └─ fsworkspaceフォールバック
                             │                    └─ [失敗] → fsworkspaceFailメッセージ記録
                             └─ [成功] → didLoadDubProject()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| extension.d | `source/served/extension.d` | ソース | delayedProjectActivation関数内のDUB初期化失敗処理、getPossibleSourceRoots関数 |
| types.d | `source/served/types.d` | ソース | Workspace.startupError メソッド、startupErrorNotifications |
| translate.d | `source/served/utils/translate.d` | ソース | エラーメッセージの翻訳機能 |
| en.txt | `views/en.txt` | リソース | d.ext.dubFail, d.ext.fsworkspaceFail メッセージ |
