Lesson 10 / Chapter 7
低レベルの例外をそのまま投げると意味が伝わらない
<?php
function loadUser(int $id) {
try {
// DB アクセス (失敗すると PDOException)
$row = dbFetch($id);
} catch (PDOException $e) {
throw $e; // ← そのまま投げる
}
return $row;
}
- 呼び出し元には
PDOException がそのまま伝わる
- 「DB の話」が「業務ロジック」のレイヤーまで漏れてしまう
上位の意味で包み直す
<?php
class UserLoadError extends Exception {}
function loadUser(int $id) {
try {
$row = dbFetch($id);
} catch (PDOException $e) {
throw new UserLoadError("ユーザー読み込み失敗", 0, $e);
}
return $row;
}
- catch で受けた後、
UserLoadError という 業務的な名前 の例外を投げ直す
- 呼び出し元は「ユーザーの読み込みが失敗した」とだけ知れば良い
第 3 引数で元の例外を保持できる
<?php
throw new UserLoadError("読み込み失敗", 0, $e);
// ↑ message code previous
- 第 3 引数に元の例外を渡せる
- 後で
$e->getPrevious() で元の例外を取り出せる
- ログには両方残せるので、デバッグ情報を失わない
レイヤー間の翻訳パターン
低レベル 中レベル 高レベル
PDOException → UserRepositoryException → ApplicationError
(DB の事情) (業務的に何が起きたか)
- 各層で適切な名前に「翻訳」していく
- 上の層は下の層の実装詳細を知らなくて良い
このチャプターでできるようになること
✅ catch した例外を別の例外で包んで再 throw できる
✅ レイヤーに応じて例外の名前を変える発想を持てる
✅ previous で元の例外を保持できると知っている
関連: 同トピック内の他チャプター (このチャプターは採点ドリル無し)