# 通知設計書 9-アップデート失敗通知

## 概要

本ドキュメントは、Oh My Zshのアップデート機能におけるバックグラウンド更新失敗時の通知について、その設計仕様を定義するものである。

### 本通知の処理概要

Oh My Zshは、バックグラウンド更新モード（background-alpha）で更新が失敗した場合に、次回のプロンプト表示時に赤色のエラーメッセージを表示する機能を提供する。エラーの詳細情報も黄色で表示される。

**業務上の目的・背景**：バックグラウンド更新モードは、シェル起動時にユーザーの操作を待たずに自動的に更新を実行する実験的な機能である。更新がバックグラウンドで失敗した場合、ユーザーはその事実を把握し、必要に応じて手動で問題を解決する必要がある。エラーメッセージを赤色で目立たせることで、ユーザーが問題に気付きやすくなる。

**通知の送信タイミング**：バックグラウンド更新が失敗した後、次回のprecmdフック（プロンプト表示直前）で_omz_bg_update_status関数が呼び出され、.zsh-updateファイルのEXIT_STATUS!=0を検出した時点で通知が表示される。

**通知の受信者**：シェルを使用しているユーザー自身。ターミナル上に赤色のエラーメッセージと黄色の詳細情報が表示される。

**通知内容の概要**：「[oh-my-zsh] There was an error updating:」という赤色のメッセージに続いて、黄色でエラー詳細が表示される。

**期待されるアクション**：受信者はエラー内容を確認し、問題を特定して手動で解決する。必要に応じて `omz update` コマンドを手動で実行してエラーの詳細を確認する。

## 通知種別

ターミナルテキスト出力（カラー付き）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（print -P / printf によるテキスト出力） |
| 優先度 | 高（エラー通知） |
| リトライ | 無し |

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

現在のシェルセッションの標準出力に対してメッセージを出力する。

## 通知テンプレート

### ターミナル出力の場合

| 項目 | 内容 |
|-----|------|
| プレフィックス | `[oh-my-zsh]` |
| メッセージ | `There was an error updating:` |
| 色（メッセージ） | 赤色（%F{red}...%f） |
| エラー詳細 | ERROR変数の内容 |
| 色（詳細） | 黄色（${fg[yellow]}...${reset_color}） |

### 本文テンプレート

```
[oh-my-zsh] There was an error updating:

<エラー詳細>
```

（実際の表示はメッセージが赤色、詳細が黄色）

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| N/A | - | - | 添付ファイルなし |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| ERROR | エラーメッセージ詳細 | .zsh-updateファイル | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| シェルフック | precmd（_omz_bg_update_status） | EXIT_STATUS!=0 かつ update_mode=background-alpha | バックグラウンド更新失敗時 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| update_mode != background-alpha | バックグラウンド更新モードでない場合 |
| EXIT_STATUS = 0 | 更新が成功した場合（成功通知に遷移） |
| EXIT_STATUS/ERRORが未設定 | 更新結果がまだ.zsh-updateに書き込まれていない場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[precmd フック] --> B[_omz_bg_update_status呼び出し]
    B --> C{.zsh-updateファイル存在?}
    C -->|No| D[return 1]
    C -->|Yes| E[ファイル読み込み]
    E --> F{EXIT_STATUS/ERROR設定済み?}
    F -->|No| D
    F -->|Yes| G{EXIT_STATUS = 0?}
    G -->|Yes| H[成功メッセージ表示]
    G -->|No| I[エラーメッセージ表示]
    I --> J[エラー詳細表示]
    J --> K[update_last_updated_file]
    H --> K
    K --> L[フック解除]
    L --> M[終了]
    D --> M
```

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

### 参照テーブル一覧

本通知はデータベースを使用しない。ファイルとシェル変数で状態管理を行う。

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| N/A | - | データベース不使用 |

### 参照ファイル一覧

| ファイル | パス | 用途 |
|---------|------|------|
| .zsh-update | `$ZSH_CACHE_DIR/.zsh-update` | EXIT_STATUS、ERROR、LAST_EPOCHを保存 |

### ファイル内容形式（失敗時）

```
LAST_EPOCH=<日数>
EXIT_STATUS=<0以外のエラーコード>
ERROR='<エラーメッセージ>'
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ファイル未存在 | .zsh-updateが存在しない | return 1で終了 |
| フィールド未設定 | EXIT_STATUS/ERRORが空 | return 1で終了（次回再試行） |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 毎precmdで再試行（結果が書き込まれるまで） |
| リトライ間隔 | プロンプト表示ごと |
| リトライ対象エラー | EXIT_STATUS/ERROR未設定 |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 表示頻度 | 更新失敗時に1回のみ（表示後にフック解除） |

### 配信時間帯

制限なし（precmd実行時）

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

- エラーメッセージにはgitコマンドの出力が含まれる可能性がある
- ローカル出力のみであり、ネットワーク経由での送信は行われない
- エラーメッセージに機密情報が含まれる可能性は低いが、パス情報等が含まれる場合がある

## 備考

- print -P でzshのプロンプト展開を使用して色付きテキストを表示
- %F{red}は前景色を赤に設定、%fはリセット
- ${fg[yellow]}と${reset_color}はzsh/colors変数を使用
- エラーメッセージは.zsh-updateファイルのERROR変数から取得
- ERROR変数はシングルクォートでエスケープされて保存される（107行目）
- 失敗メッセージ表示後、update_last_updated_fileでEXIT_STATUS/ERRORをクリア
- _omz_bg_update_statusフックは表示後に自動的に解除される

---

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

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

### 推奨読解順序

#### Step 1: 更新失敗時の結果保存を理解する

バックグラウンド更新が失敗した場合の結果保存を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | check_for_upgrade.sh | `tools/check_for_upgrade.sh` | 129-133行目の更新失敗時の処理を確認 |

**主要処理フロー**:
- **130行目**: `exit_status=$?` - 終了ステータス取得
- **131行目**: `update_last_updated_file $exit_status "$error"` - エラー情報保存

#### Step 2: エラー情報の保存形式を理解する

update_last_updated_file関数でのエラー保存を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | check_for_upgrade.sh | `tools/check_for_upgrade.sh` | 104-109行目のエラー情報保存処理を確認 |

**主要処理フロー**:
- **106行目**: `EXIT_STATUS=${exit_status}` - 終了ステータス保存
- **107行目**: `ERROR='${error//\'/'}'` - エラーメッセージ保存（シングルクォートエスケープ）

#### Step 3: エラー表示処理を理解する

_omz_bg_update_status関数でのエラー表示を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | check_for_upgrade.sh | `tools/check_for_upgrade.sh` | 281-284行目のエラー表示処理を確認 |

**主要処理フロー**:
- **281行目**: `elif [[ "$EXIT_STATUS" -ne 0 ]]; then` - エラー判定
- **282行目**: `print -P "\n%F{red}[oh-my-zsh] There was an error updating:%f"` - エラーメッセージ表示
- **283行目**: `printf "\n${fg[yellow]}%s${reset_color}" "${ERROR}"` - エラー詳細表示

#### Step 4: upgrade.shでのエラー発生を理解する

実際の更新処理でエラーが発生するケースを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | upgrade.sh | `tools/upgrade.sh` | 280-283行目のエラー処理を確認 |

**主要処理フロー**:
- **280-283行目**: git pullが失敗した場合のエラーメッセージ表示

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

```
[シェル起動]
    │
    ├─ check_for_upgrade.sh 読み込み
    │      │
    │      └─ [update_mode=background-alpha]
    │             │
    │             └─ _omz_bg_update (253-263行目)
    │                    │
    │                    ├─ (handle_update) &| サブシェルで実行
    │                    │      │
    │                    │      └─ update_ohmyzsh
    │                    │             │
    │                    │             └─ upgrade.sh 実行（失敗）
    │                    │                    │
    │                    │                    └─ update_last_updated_file $exit_status "$error"
    │                    │
    │                    └─ add-zsh-hook precmd _omz_bg_update_status
    │
[次回 precmd]
    │
    └─ _omz_bg_update_status (265-296行目)
           │
           ├─ .zsh-update ファイル読み込み
           │
           ├─ [EXIT_STATUS != 0?]
           │      │
           │      └─ Yes ──▶ print -P "%F{red}[oh-my-zsh] There was an error updating:%f"
           │                 printf "${fg[yellow]}%s${reset_color}" "${ERROR}"
           │
           ├─ update_last_updated_file (クリア)
           │
           └─ add-zsh-hook -d precmd _omz_bg_update_status (フック解除)
```

### データフロー図

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

upgrade.sh 実行結果 ────────▶ update_last_updated_file
(EXIT_STATUS!=0)                   │
(stderr → ERROR)                   │
                                   ▼
                            .zsh-update ファイル
                            LAST_EPOCH=xxx
                            EXIT_STATUS=<エラーコード>
                            ERROR='<エラーメッセージ>'
                                   │
                                   ▼
                            _omz_bg_update_status
                                   │
                                   ├─ エラーメッセージ表示 ──▶ stdout (赤色)
                                   │                           │
                                   │                           ▼
                                   │              "\n%F{red}[oh-my-zsh] There was an error..."
                                   │
                                   └─ エラー詳細表示 ─────────▶ stdout (黄色)
                                                                │
                                                                ▼
                                                         "${ERROR}"
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| check_for_upgrade.sh | `tools/check_for_upgrade.sh` | ソース | バックグラウンド更新とエラー表示のロジック |
| upgrade.sh | `tools/upgrade.sh` | ソース | 実際の更新処理を実行、エラーメッセージ生成 |
| .zsh-update | `$ZSH_CACHE_DIR/.zsh-update` | データ | 更新結果（EXIT_STATUS、ERROR）を保存 |
