---
paths: ["src/**", "scripts/**"]
---

# エラーハンドリング方針 (Error Handling)

例外を raise / 捕捉するコード（`src/**`・`scripts/**`）を書くときは本ルールに従うこと．コーディング全般の規約は `.claude/rules/coding-style.md` を参照する．

## 例外の使い分け (Exception Types)

| 状況 | 送出する例外 |
| --- | --- |
| ユーザー入力（設定 YAML・manifest・画像ファイル等）の内容・形式の問題 | `ValueError` に統一して raise |
| 内部論理エラー（到達しないはずの分岐・不変条件違反等） | `RuntimeError` |
| pydantic を使うバリデーション | `pydantic.ValidationError` をそのまま伝播（握りつぶさない） |

## データ整合性は fail fast (Fail Fast on Data)

機械学習では**静かな除外が評価を歪める**ため，データの問題は黙って飛ばさず止める．

- `patient_id` の欠落・未知のラベル値・重複行・読めない画像は raise する
- 意図的に除外する行は manifest の `note` 列に理由を明示し，除外件数をログに出す（人間が判断できるようにする）
- 「とりあえず `try` で囲んで `continue`」は禁止．クラス分布が静かに変わり，結果の解釈を誤る

## 個人情報を出さない (No PII in Messages)

例外メッセージ・ログに患者 ID・画像ファイル名を含めない．位置は行番号・件数で示す．

```python
raise ValueError(f"manifest の {row_number} 行目: patient_id が空である")
```

## 方針 (Policy)

- **最小限主義**: 独自例外クラスの階層は導入しない．上表の標準例外で表現できる範囲に留め，足りなくなった時点で検討する
- **メッセージは日本語可**: 原因と対処が分かる具体的な内容にする（どのフィールド・何行目が不正か）
- **握りつぶさない**: `except:` で例外を無言で捨てない．捕捉するなら再送出するか，ログを残した上で明示的に処理する
- **境界で検証する**: 入力の検証は入口（CLI・スキーマ読込・manifest 読込）で行い，学習ループ・指標計算は「検証済みの正しい入力が来る」前提で書く（`.claude/rules/project-structure.md` の依存方向・純関数優先と対応する）

## 参考 (References)

- [Python 公式ドキュメント — 組み込み例外](https://docs.python.org/3/library/exceptions.html)
- [Pydantic — Error Handling](https://docs.pydantic.dev/latest/errors/errors/)
