# 通知設計書 32-upgradeトップレベルエラー

## 概要

本ドキュメントは、`@tailwindcss/upgrade` パッケージのupgradeコマンド実行時に、`run()` 関数内でキャッチされなかった未処理エラーが発生した場合に `console.error` でエラー情報を出力し、プロセスを異常終了させる通知機能の設計書である。

### 本通知の処理概要

upgradeコマンドの最上位レベルで `run()` 関数のPromise chainにおける `.catch()` ハンドラにより、`run()` 関数内部で処理されなかったすべてのエラーをキャッチし、`console.error` でエラー内容をコンソール標準エラー出力に表示した後、`process.exit(1)` でプロセスを異常終了（終了コード1）させる。

**業務上の目的・背景**：`@tailwindcss/upgrade` は Tailwind CSS v3 から v4 へのマイグレーションを自動化するCLIツールである。マイグレーション処理は多岐にわたり（CSS解析、JavaScript設定ファイルの移行、テンプレートの移行、依存パッケージの更新など）、各処理ステップには個別のtry-catchによるエラーハンドリング（通知No.6で定義）が実装されている。しかし、予期しないエラーや個別のハンドラで捕捉できないシステムレベルのエラーが発生する可能性がある。本通知は、そのような未処理エラーに対する最終的なセーフティネットとして機能し、エラー情報を失わずにユーザーに伝達することを目的としている。

**通知の送信タイミング**：`run()` 関数がrejectされたPromiseを返した場合、すなわち `run()` 関数内部でthrowされたエラーが関数内部の個別try-catchブロックで捕捉されなかった場合に発生する。`.catch((err) => { ... })` で捕捉される。

**通知の受信者**：upgradeコマンドを実行している開発者。コンソール標準エラー出力（stderr）を通じて受信する。

**通知内容の概要**：`console.error(err)` によりエラーオブジェクトがそのまま出力される。Node.jsの `console.error` の標準動作により、Errorオブジェクトの場合はスタックトレースを含む完全なエラー情報が出力される。文字列やその他のオブジェクトの場合はその値がそのまま出力される。

**期待されるアクション**：開発者はエラーの内容とスタックトレースを確認し、問題の原因を特定する。必要に応じて `--force` フラグの使用、環境の修正、またはバグレポートの提出を行う。プロセスが終了コード1で終了するため、CI/CDパイプラインではビルド失敗として扱われる。

## 通知種別

コンソールエラー出力（`console.error` による標準エラー出力）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 高（プロセス異常終了を伴う） |
| リトライ | なし |

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

コンソール標準エラー出力に直接書き込むため、送信先の動的決定は行われない。`console.error` を通じてNode.jsプロセスの標準エラーストリーム（stderr）に出力される。

## 通知テンプレート

### コンソール出力の場合

| 項目 | 内容 |
|-----|------|
| 出力先 | stderr（`console.error`） |
| 形式 | テキスト（Node.jsのデフォルトフォーマット） |

### 本文テンプレート

```
{Error オブジェクト}
```

Node.jsの `console.error` がエラーオブジェクトを標準フォーマットで出力する。Errorオブジェクトの場合、典型的な出力は以下のようになる：

```
Error: {エラーメッセージ}
    at {関数名} ({ファイルパス}:{行番号}:{列番号})
    at {関数名} ({ファイルパス}:{行番号}:{列番号})
    ...
```

### 添付ファイル

該当なし（コンソール出力のため添付ファイルは存在しない）

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| `err` | `.catch()` ハンドラで受け取ったエラーオブジェクト | `run()` 関数からrejectされたPromise | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| CLI実行 | `npx @tailwindcss/upgrade` コマンド実行時 | `run()` 関数が未処理の例外でrejectされること | `run()` 関数内の個別try-catchで捕捉されなかったエラーが対象 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| `run()` が正常完了した場合 | `.then()` ハンドラが呼ばれ `process.exit(0)` で正常終了する |
| `run()` 内部のtry-catchでエラーが処理された場合 | 個別のエラーハンドラ（通知No.6）で処理されたエラーは `run()` 関数自体のrejectには至らない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[npx @tailwindcss/upgrade 実行] --> B[run 関数呼び出し]
    B --> C{run 関数の結果}
    C -->|正常完了 .then| D[process.exit 0]
    C -->|未処理エラー .catch| E[console.error err]
    E --> F[process.exit 1]
```

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

### 参照テーブル一覧

該当なし（データベースは使用しない）

### 更新テーブル一覧

該当なし（データベースは使用しない）

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 未処理のランタイムエラー | `run()` 関数内で予期しない例外が発生し、個別のtry-catchで捕捉されなかった場合 | エラー内容をstderrに出力し、終了コード1でプロセスを終了する |
| 非同期処理の未処理reject | `run()` 関数内のPromiseがrejectされ、await先のtry-catchで捕捉されなかった場合 | 同上 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（プロセスが終了するため） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | なし |
| 1日あたり上限 | なし |

### 配信時間帯

制限なし（コマンド実行時に随時出力）

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

- スタックトレースにはファイルパスが含まれるため、CIログを公開する場合はサーバー内部パスが露出する可能性がある
- エラーオブジェクトに環境変数や設定ファイルの内容が含まれる可能性があるが、upgradeツールの特性上、秘密情報が含まれるリスクは低い

## 備考

- 本通知はupgradeコマンドの最終防衛ラインであり、通常の運用では発生しないことが期待される
- `run()` 関数内の各処理ステップ（CSS解析、設定ファイル移行、テンプレート移行など）には個別のエラーハンドリング（通知No.6）が実装されており、それらで処理されたエラーは本通知の対象外となる
- `process.exit(1)` により終了コード1が返されるため、CI/CDパイプラインでは失敗ステータスとして認識される
- `.then(() => process.exit(0))` により正常完了時は終了コード0が返される

---

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

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

### 推奨読解順序

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

本通知で扱うデータは、JavaScriptの標準的なErrorオブジェクト（またはthrowされた任意の値）である。特別なデータ構造はない。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/@tailwindcss-upgrade/src/index.ts` | 362-367行目: `run()` のPromise chainで `.catch((err) => {...})` のハンドラ。`err` の型はany |

**読解のコツ**: `run()` はasync関数であるため、返却値はPromiseとなる。そのPromiseに `.then()` と `.catch()` をchainすることで成功時・失敗時の処理を分岐している。

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

upgradeコマンドのエントリーポイントは `index.ts` のトップレベルコードである。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/@tailwindcss-upgrade/src/index.ts` | 1-42行目: import文、CLIオプション定義、`--help` ハンドリング |
| 2-2 | index.ts | `packages/@tailwindcss-upgrade/src/index.ts` | 43-360行目: `run()` 関数の定義。全マイグレーション処理を包含するasync関数 |
| 2-3 | index.ts | `packages/@tailwindcss-upgrade/src/index.ts` | 362-367行目: `run()` 呼び出しとPromise chain |

**主要処理フロー**:
1. **362行目**: `run()` を呼び出し（async関数なのでPromiseを返す）
2. **363行目**: `.then(() => process.exit(0))` - 正常完了時に終了コード0で終了
3. **364-366行目**: `.catch((err) => { console.error(err); process.exit(1) })` - エラー時にエラー内容を出力し終了コード1で終了

#### Step 3: run()関数内の個別エラーハンドリングを理解する

本通知が発生する条件を理解するために、`run()` 関数内でどのようなエラーが個別に処理されているかを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.ts | `packages/@tailwindcss-upgrade/src/index.ts` | 53-59行目: Gitディレクトリの汚れチェック（`process.exit(1)` で終了するため `.catch()` には到達しない） |
| 3-2 | index.ts | `packages/@tailwindcss-upgrade/src/index.ts` | 66-85行目: バージョン不一致チェック（`process.exit(1)` で終了するため `.catch()` には到達しない） |
| 3-3 | index.ts | `packages/@tailwindcss-upgrade/src/index.ts` | 112-116行目: スタイルシートロード結果のエラー処理（エラーを表示するが `run()` は継続） |
| 3-4 | index.ts | `packages/@tailwindcss-upgrade/src/index.ts` | 124-128行目: スタイルシート解析のtry-catch |
| 3-5 | index.ts | `packages/@tailwindcss-upgrade/src/index.ts` | 133-141行目: 設定リンクのtry-catch |
| 3-6 | index.ts | `packages/@tailwindcss-upgrade/src/index.ts` | 206-209行目: 個別スタイルシート移行のtry-catch |
| 3-7 | index.ts | `packages/@tailwindcss-upgrade/src/index.ts` | 214-218行目: スタイルシート分割のtry-catch |

**読解のコツ**: `run()` 関数内の個別try-catchでは `error()` 関数（stderrへの出力）でエラーを通知するが、`run()` 関数自体はrejectされない。本通知（No.32）はこれらの個別ハンドラで捕捉されないエラーが対象となる。

#### Step 4: 出力ユーティリティを理解する

`run()` 関数内の個別エラー出力と本通知（トップレベルエラー）の違いを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | renderer.ts | `packages/@tailwindcss-upgrade/src/utils/renderer.ts` | 116-118行目: `error()` 関数。`run()` 内部の個別エラーハンドラが使用する。stderrへの整形出力 |
| 4-2 | index.ts | `packages/@tailwindcss-upgrade/src/index.ts` | 365行目: `console.error(err)` - 本通知。Node.js標準のエラー出力であり、整形は行われない |

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

```
index.ts (トップレベルコード)
    |
    +---> run() (43行目: async関数)
    |         |
    |         +---> isRepoDirty() (53行目)
    |         +---> version.installedTailwindVersion() (62行目)
    |         +---> Stylesheet.load() (109行目) -- try-catch あり
    |         +---> analyzeStylesheets() (125行目) -- try-catch あり
    |         +---> linkConfigsToStylesheets() (134行目) -- try-catch あり
    |         +---> migrateJsConfig() (159行目)
    |         +---> migrateStylesheet() (199行目) -- try-catch あり
    |         +---> splitStylesheets() (215行目) -- try-catch あり
    |         +---> migrateTemplate() (324行目)
    |         +---> migratePostCSSConfig() (348行目)
    |
    +---> .then(() => process.exit(0)) (363行目: 正常終了)
    |
    +---> .catch((err) => {           (364行目: 本通知)
              console.error(err)       (365行目)
              process.exit(1)          (366行目)
          })
```

### データフロー図

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

npx @tailwindcss/upgrade
        |
        v
   run() 関数実行
        |
        +--- 正常完了 ---------> .then() ---------> process.exit(0)
        |
        +--- 未処理エラー -----> .catch(err) -----> console.error(err) --> stderr
                                                         |
                                                    process.exit(1)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/@tailwindcss-upgrade/src/index.ts` | ソース | upgradeコマンドのメインエントリーポイント。`run()` 関数定義とトップレベルエラーハンドリング |
| renderer.ts | `packages/@tailwindcss-upgrade/src/utils/renderer.ts` | ソース | `error()`, `info()`, `success()` などのコンソール出力ユーティリティ。`run()` 内部の個別エラーハンドリングで使用される |
| args.ts | `packages/@tailwindcss-upgrade/src/utils/args.ts` | ソース | CLIオプション解析ユーティリティ |
| git.ts | `packages/@tailwindcss-upgrade/src/utils/git.ts` | ソース | Gitリポジトリ状態チェック（`isRepoDirty`） |
| version.ts | `packages/@tailwindcss-upgrade/src/utils/version.ts` | ソース | バージョン比較ユーティリティ |
| help/index.ts | `packages/@tailwindcss-upgrade/src/commands/help/index.ts` | ソース | ヘルプ表示コマンド |
