トップ «前の日記(2014-11-01) 最新 次の日記(2014-11-04)» 編集

日々の破片

著作一覧

2014-11-03

_ 予期するな、待機せよ

ひどいエラー処理のJavaプログラムの大群を目の前にしてうんざりしまくっている。
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());
  ...
}

ちゃんちゃん。


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|05|06|07|08|09|10|

ジェズイットを見習え