質問: **前提** ・フレームワークが下記のような例外処理を用意しています ・フレームワークでは、RuntimeExceptionをキャッチしていません(投げてもいません) ``` public function hoge() { try { if () { throw new フレームワークが定義しているException1(); } } catch (フレームワークが定義しているException1 $e) { } catch (フレームワークが定義しているException2 $e) { } } ``` --- **質問1** ・アプリケーション層で独自に(例えば下記のような)例外処理を作成しても良いのでしょうか? ・try ~ catch 文は複数あっても良い? ・それとも一つにまとめるべき? ``` try { switch () { case 1: throw new ユーザ定義Exception(); case 2: throw new RuntimeException(); default: throw new RuntimeException(); } } catch (ユーザ定義Exception $e) { } catch (RuntimeException $e) { } ``` --- **質問2** ・RuntimeExceptionはフレームワーク側で実装すべき例外処理なのでしょうか? ・予め用意されていたクラスなのでもしかしてそうかもと思ったのですが、関係ない? --- **質問3** ・今回は違うのですが、例えばフレームワーク側でRuntimeExceptionをスローかつキャッチしているのにも関わらず、アプリケーション側でもRuntimeExceptionをスローかつキャッチするのは駄目でしょうか? ・例外クラス名は重複してはいけない? ・あるいは先に書いたものだけ実行される、とかそう言うルールはあるでしょうか?
回答: 例外はどこにもキャッチされなければ最終的に`Uncaught Exception ...`というメッセージ付きで致命的エラーとして処理されます。つまり特に何も設定していなければそこでプログラムは停止してしまいます。 しかしフレームワークであれば、大抵は set_exception_handler を使ってデフォルトハンドラを用意することで、どこにもキャッチされなかった例外をフレームワーク側で処理しているものと思われます。 そのことを念頭に置いた上で、個々見ていきます。 > > アプリケーション層で独自に(例えば下記のような)例外処理を作成しても良いのでしょうか? > > > スローした例外をキャッチしなかったり、あるいは上位層に再スローする、ということをしない限り、つまり当該 function 内に影響が閉じている限り差し支えないと思います。 独自の例外を上位層にスローしてよいかどうかは、フレームワークの作りに依存します。 > > try ~ catch 文は複数あっても良い? それとも一つにまとめるべき? > > > ケースバイケースです。実装している処理のどこからどこまでが一つの塊として処理すべきなのか、で決まります。 > > RuntimeExceptionはフレームワーク側で実装すべき例外処理なのでしょうか? > > 予め用意されていたクラスなのでもしかしてそうかもと思ったのですが、関係ない? > > > 上述のデフォルトハンドラが設定されていたならば、個々の場面で明示的に`RuntimeException`をキャッチする必要性は薄くなります。SPL Exceptions Class Tree を見ればわかるように、`RuntimeException`は総括的な例外なのでデフォルトハンドラでキャッチするのが相応しいと言えます。 > > 今回は違うのですが、例えばフレームワーク側でRuntimeExceptionをスローかつキャッチしているのにも関わらず、アプリケーション側でもRuntimeExceptionをスローかつキャッチするのは駄目でしょうか? > > > フレームワーク側の例外処理ポリシーによります。上述したように、自分で書いた function 内に影響が閉じているのであれば問題はありませんが、自分で書いた処理の中でさらにフレームワークのライブラリを呼び出しているのであれば、呼び出し先で発生した例外を握りつぶすことにもなりかねないので、その辺りの見極めが必要となります。 > > 例外クラス名は重複してはいけない? あるいは先に書いたものだけ実行される、とかそう言うルールはあるでしょうか? > > > 例外クラスに限らず、同一のクラス名は宣言できません。クラス名が衝突した場合はエラーとなります。同一にしたい場合は名前空間を使う必要があります。 ところで例外設計の一般論としては`RuntimeException`を直接スローするのは好ましくないことは付け加えておきたいと思います。これは実行時例外を表す総括的なクラスなので、少々面倒でも、名が体を表している例外クラスを別途定義してそれをスローするようにすべきでしょう。