概要
例外についてちゃんと理解できていなかったのでまとめる。
例外とスコープ
自分は今までDBのトランザクション処理等でTryCatchを多様してきた。
特に考えず、呪文のように下記のような書き方をしていた。
try {
DB::beginTransaction();
// DB更新処理
DB::commit();
} catch (\Throwable $e) {
DB::rollBack();
throw $e;
}
まずこれがどういうことなのかを簡単にまとめる。
上記の処理はまずtryブロックの中が実行される。tryブロックの中の処理を実行中に何かしらの例外が発生したとする。
投げられた例外はどんな種類だろうと$e
に入った状態でcatchブロックの中が実行される。
例外が発生したのでDBの更新処理はロールバックして処理の前の状態に戻す。
その後、throw $e
で意図的に再度受け取った例外を発生させて、App\Exceptions\Handler
クラスで例外のハンドリングが行われる。
TryCatchはローカルスコープと呼ばれる。ローカルスコープ内で例外を受け取った場合、ローカルスコープ内より外には例外発生がわからない。そのためcatchブロックの中でわざわざもう一度throw $e
をして「例外を発生させてlaravelの処理を止める」必要がある。
上記の「例外を発生させてlaravelの処理を止める」はグローバルスコープで行われる。これはApp\Exceptions\Handler
で例外がハンドリングされ、結果laravelが例外を出して処理が停止してくれる。
TryCatchが設定されている場合、例外はCatchブロックの中が実行されるだけでthrow $e
が書かれてなかったら処理は止まらないはず。
逆にTryCatchが設定されていない場所で例外が発生するとApp\Exceptions\Handler
で例外がハンドリングされlaravelの処理が止まる。