ただエラーを出すだけのUIからユーザーを導くリカバリーUIへの変化

エラー処理は 「失敗しました」 で終わってはいけない。 DeBlog[0]

エラー処理UX設計ユーザー体験開発
要約を表すロボットのアイコンAI 要約
-この記事は mlx-community/gemma-3-4b-it-4bit によって要約されました

エラー処理を『失敗』というメッセージ表示に留めてしまうと、問題の根本原因や、次に取るべき行動が分からなくなり、ユーザー体験を損なう。エラー処理は、原因、担当者、行動という3つの観点で分解し、失敗後の流れを設計することで、より良いUXを実現できる。

昔の自分は、エラー処理をかなり軽く見ていました。
「保存に失敗しました」「通信エラーです」と出せば、それで十分だと思っていたからです。

でも実際の開発では、それでは足りません。

同じ「投稿できなかった」でも、原因は違うし、次に動くべき人も違うし、取るべき対応も違うからです。
つまりエラー処理は、失敗を表示する処理ではなく、失敗したあとにどう立て直すかを設計することです。

この記事では、「投稿ボタンを押したのに投稿できなかった」という場面を例に、エラー処理をどう整理すれば設計しやすくなるのかを、初学者向けに絞って書きます。

1. エラー処理を「表示処理」だと思うと設計を誤る

エラー処理を「失敗したときにメッセージを出すこと」だと捉えると、設計は浅くなります。

たとえば、保存に失敗したらメッセージを出す。通信に失敗したらアラートを出す。
この発想自体は間違いではありません。

ただ、それだけで終わると、

  • なぜ失敗したのか
  • 誰がそれを解決するのか
  • 次に何を起こすべきか

が抜け落ちます。

その結果、ユーザーは「失敗したこと」だけを知らされ、どう動けばいいのか分からなくなります。

つまり、エラー処理を表示処理としてだけ見ると、
失敗の説明はできても、失敗からの回復は設計できません。

2. エラー処理は3つの観点で分解すると整理しやすい

エラー処理は、ひとまとめに「エラー」と見ないほうが整理しやすいです。
少なくとも、次の3つに分けて考えると崩れにくくなります。

  • 原因は何か
  • 誰が次に動くか
  • 次に何をするべきか

たとえば、投稿ボタンを押して失敗したとしても、中身はこう分かれます。

  • 投稿文が未入力で、ユーザーが修正すれば解決する
  • ログイン切れで、再ログインが必要
  • 外部サービスとの連携切れで、再連携が必要
  • 通信の一時不良で、少し待てば通る
  • サーバー側の不具合で、ユーザーでは解決できない

見た目は全部「投稿失敗」です。
でも、設計上は別物です。

ここを分けずに扱うと、全部に同じ文言を出し、全部に同じ再試行ボタンを置く、という雑な実装になります。
実装は楽でも、設計としては弱いです。

要するに、エラー処理で重要なのは、
失敗を一括りにしないことです。

3. 最初に決めるべきは「誰が次に動くか」

3つの観点の中でも、最初に決めるべきなのは「誰が次に動くか」です。

理由は単純で、ここが決まるとUIも処理方針も決まるからです。

たとえば、

  • 投稿文の未入力なら、動くのはユーザー
  • 通信の一時不良なら、まず動くのはシステム
  • サーバー障害なら、最終的に動くのは開発側

同じ失敗でも、責任の置き場が違います。

ここを曖昧にすると、本来システム側で吸収すべき失敗をユーザーに押しつけたり、逆にユーザーが修正すべき入力ミスを黙って内部再試行したりします。
それは設計がズレています。

エラー処理でまず決めるべきなのは、原因の名前ではなく、
この失敗のあと、誰に次の行動を持たせるのかです。

これが決まると、見せるべきUIも変わります。

  • ユーザーが動くなら、修正箇所や再操作の導線を出す
  • システムが動くなら、裏で再試行し、必要なら待機中であることだけを伝える
  • 開発側が動くなら、ユーザーに無駄な再操作をさせず、調査可能な形で失敗を記録する

つまり、誰が動くかを決めることは、そのままエラー処理の方針を決めることです。

4. エラー処理は「失敗のあと」を設計すること

エラー処理の本体は、失敗の検知ではありません。
失敗したあとに、何を起こすかの設計です。

たとえば同じ「投稿に失敗した」でも、原因ごとに設計は変わります。

  • 投稿文の未入力なら、入力欄へ戻し、どこを直すべきか示す
  • ログイン切れなら、再ログイン画面へ案内する
  • 外部連携切れなら、再連携の導線を出す
  • 通信の一時不良なら、即失敗にせず内部で再試行する
  • サーバー障害なら、再投稿連打を誘発しない形で失敗を知らせる

ここで大事なのは、全部を同じ「エラー表示」で片づけないことです。

ユーザーが解決できる問題なら、修正できる形で返すべきです。
逆に、ユーザーが解決できない問題なら、ユーザーに仕事を増やすべきではありません。

この区別がないと、

  • 毎回とりあえずアラートを出す
  • 何でも再試行ボタンを押させる
  • 内部障害なのに「もう一度お試しください」で逃がす

といった、よくある雑なエラー処理になります。

つまりエラー処理とは、
失敗を知らせることではなく、失敗のあとにシステムとユーザーをどう動かすかを決めることです。

5. エラー処理の質は、そのままUXの質になる

エラー処理は地味です。
でも、UXへの影響はかなり大きいです。

正常時は、多少設計が粗くても動いて見えます。 vibecodingの「10分でできた」みたいなのは大抵このクオリティです。 一方で異常時は、作りの雑さがそのまま露出します。

ではエラー処理が弱いと、ユーザーはどうなるか?

  • 何が起きたのか分からない
  • 自分が直せる問題か分からない
  • 待てばいいのか、押し直すべきか分からない
  • 同じ操作を繰り返して、さらに状態を悪化させる

これはかなり不安です。
「このアプリ、本当に大丈夫か」と思われても仕方ありません。

逆に、設計されたエラー処理は安心感を残します。

  • 直すべき入力箇所が分かる
  • 一時的な失敗は裏で吸収される
  • 再ログインや再連携が必要なら、次の導線がある
  • 失敗しても途中入力や状態が消えない

エラーが起きないことは理想です。
でも現実には多分無理です。

だから評価されるのは「失敗しないアプリ」ではなく、
失敗したときに破綻しないアプリです。

つまり、エラー処理は補助機能ではありません。
UXそのものです。

6. 【まとめ】「失敗しました」で終わらせないための見方

エラー処理を「失敗時のメッセージ表示」と捉えると、設計はそこで止まります。

でも実際に考えるべきなのは、次の3つです。

  • 原因は何か
  • 誰が次に動くか
  • 次に何をするべきか

この3つで整理すると、エラー処理はかなり考えやすくなります。

特に重要なのは、最初に「誰が動くか」を決めることです。
そこが決まれば、ユーザーに修正させるのか、システムで吸収するのか、開発側で処理すべきなのかが見えてきます。

そして、その設計の差がそのままUXの差になります。 失敗したあとにどう立て直すかまで決めて、はじめて機能は実用レベルになります。