例外メッセージ、敬語で満足でもロスロスパターン

わりとシンプルな話ですが、
10年以上この現象が止まらないので、書きました。

値をロスした例外メッセージ

とにかくこれ:

String sea = ...
Integer land = ...
Object miyage = piariLogic.moveToBonvo(sea, land);
if (miyage == null) {
    throw new DstoreException("ボンボに移動するのに失敗しました。");
}

この例外が本番で発生して緊急対応してる人
「頼むから、sea と land の値、見せてー(><」

本番で発生した場合、状況によっては、「永久に原因がわからない」ってこともありえます。でもエンジニアは対処しないといけないですよね。原因わからなければ、三日間ずっと残業デバッグ...

でも、sea と land の値がわかっていれば、5分で解決するかもしれません。

そして、それは...よくあります。

周辺の変数を出そう

なので、せめて...

String sea = ...
Integer land = ...
Object miyage = piariLogic.moveToBonvo(sea, land);
if (miyage == null) {
    throw new DstoreException("ボンボに移動するのに失敗しました: "
                       + sea + ", " + land);
}

体裁は、別に雑でいいです。

例外メッセージを見るのはエンジニアですから、というか自分かもしれませんから、ソースコードが見れる人ですから、「これがseaの値か、これがlandの値か」ってのがわかりさえすればいい。

というか、別に、「ボンボに移動するのに失敗した」ことは、スタックトレースがなどを追えばわかるので...

String sea = ...
Integer land = ...
Object miyage = piariLogic.moveToBonvo(sea, land);
if (miyage == null) {
    throw new DstoreException(sea + ", " + land);
}

最悪、日本語によるメッセージもなくてもいいです。sea と land さえあれば。

丁寧な日本語を書いている暇があったら、その周辺の変数を出しましょう。

「失敗しました」の文字を打つ指の労力を、周辺の変数を出すのに使ってください。

もはや言葉遣いはあまり価値ではない!?

さて、非常に単純な話だったはずですが、妙にこのパターンが多いのです。

そして、こういう実装をよくしてしまう方々の傾向も、少しずつわかってきました。非常に「(ある側面で)真面目」なんです。

...

1. 例外ハンドリングあまり詳しくない
2. コンストラクタがメッセージを入れろと言っている
3. ひとまず状況を書いておく
4. 誰が見るかわからないから敬語で丁寧に
5. やるべきことはやった感が出る (ちゃんと仕事した)

おしまい。

まあ、例外ハンドリングがよくわからないのは勉強不足。多くのプログラマーが異常系のプログラミングに弱いのは事実。正常系に比べて書く機会が少ないからそれは自然なこと。

別に、いざ書くときに
「ああ、わからないからいま勉強しよう」
「どうすればいいから周りに相談しよう」
ってなれば別にいいだけ。

でも、そうならない。
せめて...
「いま暫定で実装して、後で相談しよう」
になればまだいいですが、それもなかなか。

それは...

o 丁寧に書いたら怒られないかな
o 丁寧に書いたので最大限の努力はした

という心理が走ってしまうのかなと。

でも、たしかに学校ってそういう感じあったかも。正解でも丁寧じゃなかったら怒られるみたいな。逆に丁寧であれば間違ってても怒られないみたいな。

でも、この社会人になって、プログラマーになって、業務で書く例外ハンドリングにおいては、メッセージの文言が丁寧でも、デバッグする人がデバッグができなきゃ、throwする側が仕事をしたことになりません。

// A
throw new DstoreException("ボンボに移動するのに失敗しました。");
// B
throw new DstoreException("かなぶんぶんでもえびいんびーん: "
                   + sea + ", " + land);

確実に B の方が良いコードです。

...
...
...
...
...
...
...
...
...
...

おまけ。
よくこういうのも見かけます。

String sea = ...
Integer land = ...
Object miyage = piariLogic.moveToBonvo(sea, land);
if (miyage == null) {
    throw new DstoreException("moveToBonvo()がnullを戻しました。");
}

知ってるよ!

...