| 著作一覧 |
int fooBar(...) {
try {
...
...(なんかたくさん)
} catch (SQLException e) {
log("クラスFooのFooBarでSQLExceptionになったよ。" + e.getMessage());
log("パラメータは" + param1 + "," + param2 ... + "だった");
...
return DEFINED_COMMON_DB_EXCEPTION;
} catch (Exception e) {
log("クラスFooのfooBarでExceptionになったよ。" + e.getMessage());
...
return FAILED;
}
return SUCCESS;
}
戻り値でエラーかどうかを判別させるのは設計の問題だからどうでも良い。問題は、ログがまったく役に立たないことだ。
なぜ役に立たないかと言えば、このプログラムを書いた人はきっとSQLに自信がないか、またはSQLのために与えられた引数に問題があってSQLで失敗すると予期していることにある。
予期するのであれば、あらかじめ引数をチェックすれば良い。
SQLに自信がないのであれば、まさにテストをちゃんとしておけば良い。
そして、実際、そのようにコードされていたりする。
かくして、fooBarが山ほどログを吐くのだが、すべて"クラスFooのfooBarでExceptionになったよ。null"だったりする。
何が起きているかさっぱりわからねぇ。(DBが落ちているときだけは最初のcathcのログからわかるけど)
よほどへまな奴でなければ、予期しているようなエラーは運用時には起きない(ネットワークとかIOがらみのものは除く)。起きるのは、考えてもいなかったことだ。だから例外なのだ。
したがってどこで例外になるのか、それがどんな例外なのかだってわかるはずがない。何よりも重要なのは例外の種類(Java SEの典型的な例外はgetMessage()にnullを返すことすらある)と、スタックトレース、つまりWhatとWhere(When)だ。
catch (Exception e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw, true)); // autoflushって使えるのかな?(普段はPrintWriterのインスタンスを変数に入れてcloseを呼ぶようにしているのでわからない)
log("例外になった。" + e.toString() + "\r\n" + sw.toString());
...
}
ちゃんちゃん。
ジェズイットを見習え |