要点
Exception.message は ログ用 である。エラーの原因を特定するための技術的な情報を入れる場所であり、ユーザーに表示するテキストを運ぶ場所ではない。
UI に表示するエラー情報は、例外ではなく レスポンス として設計すべきである。
アンチパターン:例外が UI を運ぶ
以下は、実際のプロジェクトで見かけたコードを簡略化したものである。
|
|
例外クラスに title、imageUrl — UI の表示仕様がそのまま入っている。
この例外は、サーバーからのエラーレスポンスを変換する過程で生成される。
|
|
なぜこうなるのか
サーバー側が、エラー時に「例外の details フィールド」に UI 表示用の情報を詰めて返す設計をしている。クライアントはそれを受け取り、例外クラスに変換する。
つまり、サーバーの設計が「エラー = 例外」という前提で作られている ことが根本原因である。
何が問題か
| 問題 | 影響 |
|---|---|
| 責務の混在 | 例外がロギングと UI 表示の両方を担う。message がどちら用なのか曖昧になる |
| サーバー・クライアント間の密結合 | 例外の構造が UI の表示仕様に依存する。UI を変えるとサーバー側も変更が必要 |
| テストの困難さ | エラー表示のテストに例外の throw/catch が必要になる |
| 拡張性の欠如 | 多言語対応、エラーの種別ごとの表示分岐などが例外クラスに集中する |
正しい設計:エラーはレスポンスとして返す
サーバーは、エラー時にも 構造化されたレスポンス を返すべきである。RFC 7807(Problem Details for HTTP APIs)はその標準仕様である。
|
|
クライアント側では、このレスポンスを データクラス として扱う。例外として扱う必要はない。
|
|
エラーは「異常な状態」ではなく「想定されたレスポンスの一種」である。ユーザーへの通知が必要なエラーであればなおさら、設計されたレスポンスとして扱うのが自然である。
Exception.message の正しい使い方
Exception.message には、開発者がログを見て原因を特定できる情報 を入れる。
|
|
ユーザー向けのメッセージは、前述のようにレスポンスとして受け取るか、クライアント側で例外の種別に応じてマッピングする 1。
まとめ
Exception.message はログ用である。UI テキストを入れる場所ではない。
エラー情報をユーザーに伝える必要がある場合は、サーバーが構造化されたレスポンス(RFC 7807 等)を返し、クライアントがそれをデータとして扱う。例外の中に UI の仕様を詰め込む設計は、責務の混在と密結合を招く。
そもそもクライアント開発において、独自例外を定義する場面自体が少ない。次の記事ではこの点を掘り下げる。
-
マッピングの際、リソース ID と、リテラル文字列の混在で悩むことがある。AdaptiveString を使えばこれを解消できる。
↩︎getString のために Context を渡すのをやめる。文字列リソースの解決を View まで遅延させる設計