例外によるエラー処理の罠?
いつも読ませて頂いている Radium Software というブログに興味深い記事がありました。
http://www.radiumsoftware.com/0502.html#050207
例外を利用したエラー処理と戻り値によりエラーを判別するエラー処理についての考察です。
Javaを利用している場合、ほとんどの場合は脊髄反射的に例外を利用してエラーの発生を上層に伝えてしまっていますが、Radium Software の記事が示すように、たしかに簡単にバグとなるコードを埋め込みやすいですね。
Radium Software で触れている内容とはやや異なりますが、同種の例外が複数のメソッドから送出される可能性があり、またどのメソッドで処理に失敗したかでエラー処理を変えなければいけない場合などに、そのことを忘れてしまうと後々になって気づきづらいバグとなると思います。
たとえば、最初に以下のようなコードがあったとします。
try { func1(); } catch( FooException ex ) { // func1 失敗時のためのエラー処理 }
上記例では func1 は FooException を送出する可能性があるメソッドとして定義されています。
この後に処理が追加となり func2 も呼び出す必要が出来たとします。ここで、もし func2 も FooException を送出する可能性があるメソッドであった場合、すでに記述されている catch 節によって func2 のエラーに対して func1 のエラー処理が行なわれてしまいます。
try { func1(); func2(); } catch ( FooException ex ) { // func1 失敗時のためのエラー処理 }
このようなコードを書いた場合に、func2 が送出する可能性のある FooException のための catch 節は既に記述されているため、当たり前ですがコンパイルエラーとはなりません。
このような問題を回避するには、各 func1, func2 を別個に try で囲むか、あるいはそれぞれのエラー処理は各メソッド内で完結させるか、もしくは別の例外クラスを使用するか等等の方法が考えられます。
適切な対処を行なえば実装上は問題無いのですが、問題なのはバグが分かりづらいコードをそれと気づかずに記述できてしまうことにあると思います。
例外を使用したエラー処理を行なう場合は、注意深く、各処理の内容を考えてエラー処理を記述する必要があるということでは無いでしょうか?
ということで、これからは今まで以上に気をつけて例外を利用したいと思います。