タイトルの通りですが、PHPで例外発生中に例外スローすると、新たな例外に以前の例外が登録されます。
以前の例外はgetPrevious()
で辿ることができます。
<?php
try {
try {
throw new Exception("foo");
} finally {
throw new Exception("bar");
}
} catch (Exception $e) {
var_dump($e->getMessage()); // "bar"
var_dump($e->getPrevious()->getMessage()); // "foo"
}
catchブロックでは明示的に以前の例外を登録しないとチェーンにならない
ただし、上のような状況はfinallyブロックでしか起きません。catchブロックに入ったタイミングで例外は解消されるので、catchブロックで例外スローしてもチェーンにはならないのです。
catchブロックで同じことをしたい場合、Exceptionのコンストラクタ第三引数にキャッチした例外を渡せば同じことになります。
<?php
try {
try {
throw new Exception("foo");
} catch (Exception $e) {
throw new Exception("bar", 0, $e);
}
} catch (Exception $e) {
var_dump($e->getMessage()); // "bar"
var_dump($e->getPrevious()->getMessage()); // "foo"
}
所感
普段PHPを使っている人でもまず知らない挙動だと思ったので紹介してみました。
言語実装者の気持ちはわかるけど、そもそもfinallyブロックで例外発生するコード書くの良くないでしょとか、勝手に以前の例外を登録するんかいとか、色々ツッコミどころがあってモヤモヤしますね。