# 通知設計書 34-設定エラー

## 概要

本ドキュメントは、`@babel/core`のBabel設定検証エラー（ConfigError）に関する設計を記載する。

### 本通知の処理概要

設定エラー通知は、Babelの設定ファイル（babel.config.js、.babelrc等）やプログラマティック設定の検証時に、不正な設定を検出した場合に開発者に詳細なエラー情報を提供するメカニズムである。

**業務上の目的・背景**：Babelの設定は複雑で、多くのオプション、プラグイン、プリセットが存在する。設定の検証を早期に行い、明確なエラーメッセージを提供することで、開発者がビルド失敗の原因を素早く特定し、修正できるようにする。特に、設定ファイルの場所を示すスタックトレースの改善により、問題の特定が容易になる。

**通知の送信タイミング**：設定ファイルの読み込み・解析時、オプションの検証時、プラグイン/プリセットの解決時など、設定処理の各段階で不正を検出した時点でConfigErrorがスローされる。

**通知の受信者**：Babelを呼び出しているコード（CLI、ビルドツール、IDE等）。try-catchでエラーをキャッチして処理する。

**通知内容の概要**：エラーメッセージに加え、問題の設定ファイルのパスがスタックトレースに含まれる。V8のStack Trace APIを活用し、内部フレームを隠蔽しながら設定ファイルへの仮想フレームを挿入する。

**期待されるアクション**：開発者はエラーメッセージを参照して設定ファイルを修正する。スタックトレースに表示されるファイルパスから、問題の設定ファイルを特定できる。

## 通知種別

設定エラー（ConfigError例外）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（例外スロー） |
| 優先度 | 高（処理を中断） |
| リトライ | 無し |

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

呼び出し元のコードに対して例外をスローする。送信先の動的決定は行われない。

## 通知テンプレート

### ConfigError例外の場合

| 項目 | 内容 |
|-----|------|
| エラー型 | ConfigError（Errorを継承） |
| スタックトレース | 仮想フレームを含む（設定ファイルパス） |

### エラーメッセージテンプレート

```
{エラーメッセージ}
    at {設定ファイルパス}
```

例:
```
Config returned typeof undefined
    at /path/to/babel.config.js
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| message | エラーメッセージ | コンストラクタ引数 | Yes |
| filename | 設定ファイルパス | コンストラクタ引数 | No |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 設定読み込み | JSON解析エラー | package.jsonのbabelフィールドが不正なJSON | JSON構文エラー |
| 設定読み込み | 型不一致 | 設定が配列やundefined | オブジェクト以外の設定 |
| 設定読み込み | プロパティ不正 | .babelプロパティがオブジェクトでない | package.jsonの.babel設定 |
| 設定読み込み | キャッシュ設定不正 | api.cache()が正しく呼ばれない | 関数設定でのキャッシュ指定漏れ |
| オプション検証 | 不明なオプション | 認識されないオプションキー | タイポや非推奨オプション |
| オプション検証 | 型不一致 | オプション値の型が不正 | 例：配列を期待する場所に文字列 |
| プラグイン解決 | プラグイン未発見 | 指定されたプラグインが見つからない | パッケージ未インストール |
| プラグイン検証 | 無効なプラグイン | プラグインの形式が不正 | 関数/オブジェクト以外 |
| モジュール読み込み | ESMエラー | require()でESMを読み込み | CJS環境でESM設定ファイル |
| モジュール読み込み | TLAエラー | トップレベルawaitの使用 | CJS環境でTLAを含む設定 |
| モジュール読み込み | TypeScriptサポート | .ts/.mts設定ファイル | TSサポートが無効 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| なし | 設定エラー検出時は必ずConfigErrorがスローされる |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[設定ファイル読み込み] --> B{ファイル形式}
    B -->|JSON| C[JSON解析]
    B -->|JS/MJS| D[モジュール読み込み]
    B -->|TS/MTS| E{TSサポート有効?}
    E -->|No| F[ConfigError: TSサポート無効]
    E -->|Yes| D
    C --> G{解析成功?}
    G -->|No| H[ConfigError: JSON構文エラー]
    G -->|Yes| I[オプション検証]
    D --> J{読み込み成功?}
    J -->|No| K[ConfigError: モジュールエラー]
    J -->|Yes| L{関数設定?}
    L -->|Yes| M[関数実行・キャッシュ検証]
    M --> N{キャッシュ設定OK?}
    N -->|No| O[ConfigError: キャッシュエラー]
    N -->|Yes| I
    L -->|No| I
    I --> P{検証成功?}
    P -->|No| Q[ConfigError: オプションエラー]
    P -->|Yes| R[設定オブジェクト返却]
```

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

該当なし

### 参照テーブル一覧

該当なし

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

この機能自体がエラー通知であるため、追加のエラー処理は存在しない。

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0 |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

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

### 配信時間帯

制限なし（エラー検出時に即座にスロー）

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

- エラーメッセージにファイルパスが含まれる場合があるが、開発環境での使用を想定
- 設定ファイルの内容自体はエラーメッセージに含まれない
- スタックトレースには設定ファイルのパスが挿入される

## 備考

- V8のStack Trace API（`Error.captureStackTrace`、`Error.prepareStackTrace`）を活用
- `expectedError`でエラーをマークすることで、内部スタックフレームを隠蔽
- `injectVirtualStackFrame`で設定ファイルへの仮想フレームを挿入
- スタックトレースの操作はV8環境（Node.js、Chrome）でのみ有効、他環境ではnoopになる

---

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

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

### 推奨読解順序

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

ConfigErrorクラスの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | config-error.ts | `packages/babel-core/src/errors/config-error.ts` | ConfigErrorクラスの定義（6-12行目） |

**読解のコツ**: ConfigErrorはErrorを継承したシンプルなクラスだが、`expectedError`と`injectVirtualStackFrame`を活用してスタックトレースを操作する。

#### Step 2: スタックトレース操作を理解する

rewrite-stack-trace.tsの仕組みを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | rewrite-stack-trace.ts | `packages/babel-core/src/errors/rewrite-stack-trace.ts` | injectVirtualStackFrame関数（75-83行目） |
| 2-2 | rewrite-stack-trace.ts | `packages/babel-core/src/errors/rewrite-stack-trace.ts` | expectedError関数（85-89行目） |
| 2-3 | rewrite-stack-trace.ts | `packages/babel-core/src/errors/rewrite-stack-trace.ts` | setupPrepareStackTrace関数（120-168行目） |

**主要処理フロー**:
1. **75-83行目**: injectVirtualStackFrame - 仮想CallSiteを追加
2. **85-89行目**: expectedError - エラーを「予期されたエラー」としてマーク
3. **120-168行目**: setupPrepareStackTrace - Error.prepareStackTraceをカスタマイズ

#### Step 3: ConfigErrorの使用箇所を理解する

ConfigErrorがスローされる具体的な場面を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | configuration.ts | `packages/babel-core/src/config/files/configuration.ts` | 設定ファイル読み込み時のエラー |
| 3-2 | options.ts | `packages/babel-core/src/config/validation/options.ts` | オプション検証時のエラー（394行目） |
| 3-3 | module-types.ts | `packages/babel-core/src/config/files/module-types.ts` | モジュール読み込み時のエラー |
| 3-4 | package.ts | `packages/babel-core/src/config/files/package.ts` | package.json読み込み時のエラー |

**主要処理フロー**:
- **configuration.ts:92**: 不正なJSON設定ファイル
- **configuration.ts:102**: 設定ファイルにデフォルトエクスポートがない
- **configuration.ts:174**: 設定が検出されない
- **configuration.ts:177**: 設定が不正な型
- **configuration.ts:180**: 設定が配列（オブジェクトを期待）
- **options.ts:394**: オプション検証エラー

#### Step 4: オプション検証の詳細を理解する

オプション検証の具体的な実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | options.ts | `packages/babel-core/src/config/validation/options.ts` | バリデータセット（43-58行目） |

**主要処理フロー**:
- **43-58行目**: ROOT_VALIDATORS - ルートオプションの検証
- **60-63行目**: BABELRC_VALIDATORS - babelrc関連オプション
- **65-75行目**: NONPRESET_VALIDATORS - プリセット以外のオプション
- **77-100行目**: COMMON_VALIDATORS - 共通オプション

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

```
babel.transformSync/transformAsync
    │
    ├─ loadConfig()
    │      │
    │      ├─ readConfigFile()
    │      │      │
    │      │      ├─ readConfigJSON()
    │      │      │      └─ throw new ConfigError(...)
    │      │      │
    │      │      └─ readConfigJS()
    │      │             └─ throw new ConfigError(...)
    │      │
    │      ├─ validateOptions()
    │      │      └─ throw new ConfigError(...)
    │      │
    │      └─ resolvePlugins/Presets()
    │             └─ throw new ConfigError(...)
    │
    └─ 呼び出し元でcatch
```

### データフロー図

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

設定ファイル ───▶ ファイル読み込み ───▶ 解析
    │                                     │
    │                               ┌─────┴─────┐
    │                               ▼           ▼
    │                            成功       エラー
    │                               │           │
    │                               ▼           ▼
    │                        オプション     ConfigError生成
    │                          検証              │
    │                               │           │
    │                         ┌─────┴─────┐    │
    │                         ▼           ▼    │
    │                      成功       エラー   │
    │                         │           │    │
    └──────────────────▶ 設定       ├────────┘
       オブジェクト              │
                               ▼
                          throw error
                               │
                               ▼
                         呼び出し元
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| config-error.ts | `packages/babel-core/src/errors/config-error.ts` | ソース | ConfigErrorクラス定義 |
| rewrite-stack-trace.ts | `packages/babel-core/src/errors/rewrite-stack-trace.ts` | ソース | スタックトレース操作 |
| configuration.ts | `packages/babel-core/src/config/files/configuration.ts` | ソース | 設定ファイル読み込み |
| options.ts | `packages/babel-core/src/config/validation/options.ts` | ソース | オプション検証 |
| module-types.ts | `packages/babel-core/src/config/files/module-types.ts` | ソース | モジュール読み込み |
| package.ts | `packages/babel-core/src/config/files/package.ts` | ソース | package.json読み込み |
| config-chain.ts | `packages/babel-core/src/config/config-chain.ts` | ソース | 設定チェーン構築 |
| full.ts | `packages/babel-core/src/config/full.ts` | ソース | 完全設定構築 |
| plugins.ts | `packages/babel-core/src/config/validation/plugins.ts` | ソース | プラグイン検証 |
