良いエラーメッセージの書き方

  • 27
    Like
  • 0
    Comment

エラーには大抵「エラーメッセージ」が付いています。
自分は過去に、エラーメッセージの内容を雑にしてしまい後悔することがよくありました。
その経験から、良いエラーメッセージの書き方を考えました。

エラーメッセージを2つに分類する

まず、エラーメッセージといっても次の2つのパターンで大きく異なってきます。

  • (1) ユーザーが見るエラーメッセージ
  • (2) 開発者が見るエラーメッセージ

(1) ユーザーが見るエラーメッセージ

内部実装のことは書かないようにする

NG MySQLのクエリ実行に失敗しました 'SELECT * FROM ...'
OK 検索処理でエラーが発生しました

ソースコードの何処か~や、何のライブラリで~といったプログラマーしかわからない情報は書かないようにします。
ユーザー側からすると、謎の英語の羅列が出てきたりしてなんだか怖いですし、悪意のあるユーザーに不正行為のためのヒントを与えてしまう可能性があり危険です

たとえば、上の「わるい例」では MySQL を使っていることや、どのようなSQL文を実行しているか、テーブル名は…といった情報が見えてしまっているので攻撃のヒントを与えてしまうかもしれません。

もちろん、開発者だけが見られるエラーメッセージの場合は逆になります。(詳しくは後に)

ユーザーの入力が原因の場合、はっきりと理由を書く

NG 入力欄が不正です
OK ユーザーIDは4文字以上の英数字で入力してください

ユーザーの入力内容が原因の場合、「何が悪かったのか」具体的に出してくれないとユーザーはイライラしてしまいます。

(2) 開発者が見るエラーメッセージ

開発者用のエラーメッセージは、ユーザー用とは違って不具合が起きた場所をできるだけすばやく特定するために、詳しく、具体的にします

エラーに関わる値を具体的に出す

NG config file not found
OK config file not found: /path/to/config.ini

たとえば、「設定ファイルが見つかりませんでした」と言われても「どこの設定ファイルを開こうとしてエラーになったの・・?」と困惑してしまいます。
また、期待した値と実際の値が違った場合は、xxを期待したが、実際はyyだったのでエラーになりました というところまで具体的に出しているとわかりやすいです。

原因を特定しやすくしてくれる一文を入れる

NG table "users" not found
OK table "users" not found. have you init db?

起こったことを伝えることは重要ですが、さらに「原因はxxなのでは?」「~~を忘れていませんか?」という提案が入っていると「あぁ~そうか忘れてた!!」って気づきやすいと思います。

正しい文法でなくても、英語を使う

これは好みが分かれそうなところですが、自分は自身しか使わないようなものでもエラーメッセージは英語で書くようにしています。
その理由はこんなところです。2つ目はとても個人的な理由ですが・・

  • 文字エンコーディング関連の問題にぶつかる可能性がある
  • vimで日本語入力に切り替えるのがしんどい

しかし、普段日本語を書いていると英語でメッセージを書くのは難しいです。そこで、自分は文法は気にせずに書くようにしています。
正しい文法よりも、何が起きたのか分かれば十分と思っています。

たとえば、 user(id=1) register fail というエラーメッセージは(おそらく)文法的には変ですが、「ユーザー(ID: 1)、登録、失敗」という単語から何が起きたかはつかめます。

エラーに至るまでの履歴(スタックトレース等)を表示する

開発者としては、エラーが発生した際に「どのような経緯でエラーになったのか」が知れると非常に有用です。
大抵のプログラミング実行環境では、スタックトレースを表示する処理が用意されているので、開発者用エラーメッセージにはつけておくと良いでしょう。

複数あるものは、自身を識別する値を一緒に表示する

NG user register fail
OK [ID: 12345]user register fail

登録ユーザーや、マルチスレッドといった複数存在するものを扱っている場合、「エラーが発生したのは複数あるうちのどの個体か」を知ることで超探しやすくなります。
ユーザーIDや、スレッドID、IPアドレスなど個体を個体を特定できるものはできるだけ一緒に入れましょう。

発生時刻を細かく表示する

気がついたらエラーメッセージがたくさん出ていた、という状況の場合「いつ発生したエラーなのか」は重要な情報になります。
特に長時間起動するサーバー等ではログに複数のエラーメッセージが並ぶこともよくあるので、秒より細かい単位までしっかり時刻を表示しておくと良いでしょう。