エラー処理とUXの説明
1)なぜ重要なのか
エラーは「赤いテキスト」ではなく、スクリプトの継続です。良いUXエラー:- 何が起こったのか、次に何をすべきかを説明します、
- 入力されたデータを保存し、進捗状況の損失を防ぎます、
- 安全な繰り返しまたは代替パスを提供します、
- 利用可能なまま(SR/キーボード)とあまり明らかにしません。
2)エラーのタイポロジー(インターフェイス用)
1.データ検証(4xxクライアント):空/無効なフィールド、フォーマット、長さ、ルールの競合。
2.ビジネスルール:制限、地理的制約、KYC/KYB、重複、利用できないスロット。
3.権利/権限:役割、リソースへのアクセス、年齢制限。
4.ネットワーク/サーバー:タイムアウト、オフライン、5xx、過負荷、レート制限。
5.競合/ステータス:409/412(データ変更)、レース、ロック。
6.リソースなし:404/410、削除/転送。
7.支払いとリスク:銀行/PSPによる拒否、詐欺防止、責任あるプレーの制限。
3)チャネルおよび表示レベル
コンテキストの「ボリューム」を選択します:ルール:トースト/ホバーでクリティカルを隠さないでください。ユーザーが見ているところにメッセージがあります。
4)コピーライティングエラー
構造:原因→効果→アクション。
トーン:正直、中立、罪悪感のない。
詳細:フィールド/条件を指定し、コードとスタックを避けます。
ボタンアクション:「繰り返し」、「カードを変更」、「フィルターをリセット」、「チャットを開く」。
機密データ:表示しない(PANマスキング、個人属性)。
例
良い:"支払いは失敗しました:銀行は取引を拒否しました。別の方法を試したり、後でもう一度お試しください。
悪い: "エラー500。何かがおかしくなった"
良い: "毎日の支出制限に達しました。新しい制限を設定するか、明日を試してみてください"
良い:"ファイルが大きすぎる(最大25 MB)。ファイルを圧縮またはダウンロードしてください。
5)行動と焦点(A11y)
フォーカスのコンテキストにエラーが表示されます:フォーカスを最初のエラーのフィールドに転送します。
リビングリージョン:"role="status"(丁寧)、"role="alert" (assertive)"、critical。
Visible':focus-visible'、 contrast ≥ AA、 color (icon/text)の代替。
「aria-descripedby」を介してフィールドにメッセージをバインドします。
html
<label for = "pwd "> Password </label>
<input id="pwd" name="password" aria-describedby="pwd-err" aria-invalid="true">
<p id = "pwd-err" role = "alert"> Minimum 8 characters </p>
6) Retrai、バックオフおよびidempotency
成功の可能性がある場合、繰り返しが提供されます(ネットワーク障害、5xx、レート制限)。
指数関数バックオフ1-2-4-8 s、試みの限界、理解可能なボタン「繰り返し」。
重要な取引(レート/支払い):必須Idempotency-Key→重複を除外します。
楽観的な更新をロールバック-明確な視覚的リターン+明確化。
js async function retry(fn, attempts=3){
let wait=1000; for(let i=0; i<attempts; i++){
try{ return await fn(); }catch(e){ if(i===attempts-1) throw e; await new Promise(r=>setTimeout(r,wait)); wait=2; }
}
}
7)オフライン、タイムアウトおよび部分的な内容
オフライン:「接続なし」バナー、キャッシュへのアクセス(読み取り専用)、同期キューが表示されます。
タイムアウト:UIタイムアウト(3-5秒)→ステータス「確認待ち」……安全なやり直し/元に戻す。
部分的な成功:私達は私達が管理したものを保ちます;「同期されていない」とマークします。
8)紛争と競争力
409/412:古いデータ。「Update」を提案し、(変更された)差分を表示します。
ロック:誰がブロックを保持しているか、どのくらいの時間、「アクセスを要求する」ボタンを通知します。
9)サンプルUIテンプレート
ページバナー:html
<div class="banner banner--error" role="alert">
<strong> Connection failed. </strong> Shows cached data.
<button class =" btn btn--ghost" id = "retry "> Retry </button>
</div>
クリティカルエラーモーダル:
html
<div role="alertdialog" aria-labelledby="err-title" aria-describedby="err-desc">
<h2 id = "err-title "> Session expired </h2>
<p id = "err-desc "> Sign in again to continue. </p>
<button class = "btn "> Sign in </button>
<button class =" btn btn--ghost"> Home </button>
</div>
React ErrorBoundary(相関ID付き):
tsx function Fallback({ id, onRetry }: { id: string; onRetry: ()=>void }) {
return (
<div role="alert" className="banner banner--error">
<strong> We couldn't load the page. </strong>
<div> Try again. Код: <code>{id}</code> <button onClick={()=>navigator. clipboard. writeText (id)}> Copy </button> </div>
<button onClick = {onRetry}> Retry </button>
</div>
);
}
10)エラートークン(設計システム)
json
{
"error": {
"tones": { "danger": "#", "warning": "#", "info": "#" },
"aria": { "polite": true, "assertive": true },
"timing": { "toastMs": 3500, "retryBackoffMs": [1000,2000,4000] },
"layout": { "fieldGap": 8, "bannerIcon": 20 }
}
}
CSSプリセット:
css
.banner--error { background: var(--bg-danger); color: var(--on-danger); padding: 12px 16px; border-radius: 12px; }
.field-error { color: var(--role-danger); margin-top: 6px; font-size:.875rem; }
11)セキュリティとプライバシー
スタックトレース、内部ID、データベースパスは表示しません。
機密値(マップ、ドキュメント)をマスクします。
メッセージは攻撃者にプロンプトを送るべきではありません(例えば、アカウントが存在すること)。
サポートの場合-部品の代わりに相関ID。
json
{"level":"error","event":"payment_fail","correlation_id":"c-8f1...","user_id":"u-","route":"/pay","psp_code":"DO_NOT_EXPOSE_TO_USER"}
12)メトリクスとコントロール
INPとエラー時のLong Tasksの共有(エラーはUIを「ハング」すべきではありません)。
リトライ成功率、1000アクションあたりのエラー、復元時間。
「ヘルプ/チャット」のCTRでは、フォームの割合が低下しました。
ヒートマップ:フィールドエラーが最も頻繁に発生する場所。
13) QAチェックリスト
可用性について
- 最初の無効なフィールドに焦点を当てます。'aria-describedby'/'aria-invalid'セット。
- クリティカルメッセージ-'role=「alert」';AA ≥対照。
動作
- フォームデータはエラーで失われません。
- 明確な'再試行'と正しいバックオフがあります。
- オフラインモード/キャッシュ作業;バナーを参照してください。
コピーライティング
- 理由→アクション;技術的な専門用語と告発なし。
- テキストはローカライズされ、グリッドを壊さない。
セキュリティ
- PIIの漏出/秘密無し;セキュアコード/IDのみを表示します。
- 重要な操作に対してIdempotencyが有効になっています。
14) iGamingの詳細
レート:- UIはすぐに'busy'を記録します。遅延>3秒-「確認を待っています……。」
- 失敗時:正直な状態(「市場が閉じた」、「係数が変更された」)+安全な「再試行」。
- 二重入札を排除するためのIdempotentキー。
- 「銀行障害/PSP」と「サーバー障害」を区別します。"最初の-"別の方法を選択してください"、2番目の-'再試行'。
- 透明なKYC/AMLのステップ;リンク"なぜ必要なのですか?».
- 音色は気遣い、圧力はありません。「制限に達しました-制限を一時停止または更新します。」
- 発生しない/ネオン;AAAコントラスト、SRでの可用性。
- 制限を明確に説明し「、ルール/サポートを読む」を提案します。
15)アンチパターン
行動も文脈もなく「何かがうまくいかなかった」。
エラーの後にフォームをリセットします。
トーストで3秒間クリティカルを隠す。
テキスト/アイコンのない色のみ。
キャンセルの可能性なしに無限の後退。
内部コード/スタックトレイルを表示します。
16)設計システムにおけるドキュメンテーション
'FieldError'、 'FormError'、 'PageBanner'、 'AlertDialog'、 'ErrorBoundary'。
トーン/コントラスト/タイミングトークン、a11yプリセット、およびARIAの例。
テキストテンプレートを使用した典型的なシナリオ(検証、ネットワーク、権利、支払い)のマップ。
「Do/Don 't」:失敗/成功の指標を持つスクリーンの前/後の実数。
概要
人間の言語を話す、入力されたデータを保存する、安全な繰り返しと選択肢を提供する、アクセシビリティとプライバシーを尊重します。その後、緊急事態でさえ自信を保ち、特に賭けや支払いの重要なシナリオでは、ユーザーのパスを中断しません。