エラーとリカバリー
ハッピーパスはフラグメントをスワップします。しかし現実のアプリは セッションが切れ、編集が競合し、ボタンは二度押しされます。この ページはその地図です: ステータスコードからユーザー体験への 1 枚の 表、エラーフラグメントをスワップ可能にするページレベルの単一 スニペット、そして古典的な重複を防ぐリクエスト衛生の属性群。
ステータスコードの地図
Section titled “ステータスコードの地図”| ステータス | ユーザーが見るもの | 契約 |
|---|---|---|
422 | コントロール直下のインラインエラー | field-errors / mutating-form |
401 | ログインダイアログ。サインイン後、中断された操作が完了します | session-expiry |
409 | 競合ダイアログ — 自分を残す / 相手を取り込む | edit-conflict |
413 | エラートースト。フォームは残ります | file-upload(プロキシ上限の注記) |
5xx | HX-Trigger 経由のエラートースト。スワップなし | lazy-panel(503 ブランチ) |
| (無応答) | 再試行アラート — オフライン / タイムアウトにはルーティングすべきステータスがない。唯一のクライアント語りのエラー | network-retry |
すべてを貫くのは 2 つのドクトリンです:
- サーバーが検証者であり語り手です。 エラー UI はサーバーが レンダリングしたフラグメント(ダイアログ、ヒント、フィールド エラー)として届きます — クライアントがステータスコードから エラーメッセージを組み立てることはありません。
- ドメインの帰結には 4xx で何も返さないより、200 で真実を返す (undo-delete の 期限切れブランチ参照)。プロトコルの失敗(401/409/422)は コードを使い、下の許可のような汎用機構がルーティングできるように します。
共有する許可
Section titled “共有する許可”htmx は既定で非 2xx を一切スワップしません。契約が操縦する ステータスを、ページレベルで一度だけ許可します:
document.body.addEventListener('htmx:beforeSwap', (event) => { if ([401, 409, 422].includes(event.detail.xhr.status)) { event.detail.shouldSwap = true; event.detail.isError = false; }});これがあれば各エラーの UI を操縦するのはサーバーです —
HX-Retarget / HX-Reswap ヘッダーがフラグメントを狙い
(ログインダイアログは remote-dialog ルートへ、
フィールドエラーはフォームへ)、ページごとの配線は増えません。
各レシピのページには自分のステータスだけの版が載っています —
これはその統合形です。
二重送信の衛生
Section titled “二重送信の衛生”注文が二重になるバグはコンポーネントではなくリクエスト衛生の 問題です。属性 3 つ、すべて htmx ネイティブ:
<form data-hx-post="/orders" data-hx-sync="this:abort" data-hx-disabled-elt="find button[type=submit]" data-hx-indicator="find .hc-spinner"> … <button class="hc-button" data-variant="primary" type="submit"> Place order <span class="hc-spinner" aria-hidden="true"></span> </button></form>data-hx-sync="this:abort"— 再送信は競走せず、進行中の リクエストを中止します。data-hx-disabled-elt— ボタンはリクエストの間だけ無効化され、 エラー経路を含むすべての settle 経路で再有効化されます。 手書きのonclick無効化はエラー経路を誤り、フォームを固めます。data-hx-indicator— スピナーは 飛行中のみ表示(htmx-indicatorの CSS はhc.htmx.cssにあります)。
破壊的な操作には確認ダイアログより undo-delete を — 「聞いたが無視された」より「実行されたが取り消せる」が勝ちます。
- request-action — これらの属性が飾る、変更ボタンの基本レシピ。
- UI コピーを書く — エラーメッセージの声(「何が起きたか + どう直すか」)。
- htmx 連携 — 許可の背後にあるイベント/ライフサイクルのリファレンス。