採点されません。匿名です。 間違えることは学習の一部です。読むだけでもかまいません。

例外の再 throw (rethrow)

テクノロジ系 / exception (try / catch / throw / Exception / カスタム例外)

例外の再 throw (rethrow)

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 で元の例外を保持できると知っている

関連: 同トピック内の他チャプター (このチャプターは採点ドリル無し)