| UI or UX | UI + UX - Scoped failed-operation retry control | UI + UX - Recoverable failure surface | UI + UX - Bounded indeterminate wait indicator for a named action or region | UI + UX - Connectivity-mode and local-work continuity state |
| UI guidance | Place Retry next to the failed operation, object, or request summary, and name the exact action being retried such as Retry export or Retry payment authorization. | Render a persistent error region near the affected content with a specific failure heading, plain-language cause, preserved context, and recovery actions. | Render a compact spinner only beside, inside, or over the affected action, component, or page region, and pair it with concise text that names what is loading or processing. | Show offline status where it changes the current task, naming what remains available such as cached reports, local draft editing, queued saves, or read-only history. |
| UX guidance | Use retry when a specific operation likely failed for a transient reason and the same operation can be attempted again without losing user context or duplicating side effects. | Help users recover when expected loading, saving, validation, sync, permission, or computation fails without losing their work. | Use a loading spinner for short indeterminate waits where the system is actively working but cannot yet expose progress; resolve it quickly to content, success, cancellation, progress, or error. | Use offline state to preserve trust and task continuity when connection loss changes what users can read, edit, submit, sync, refresh, or share. |
| Good UI | A report export card says Export CSV failed, keeps the saved filters visible, shows Attempt 1 of 3, and offers Retry export with request EXP-2048. | Reports could not load appears in the report section with the saved filter, Retry, Use cached data, and Contact support actions. | A Pay invoice button becomes Processing payment with a small spinner, disables only duplicate payment actions, and leaves the invoice reference visible. | A field report says Offline: 3 edits saved on this device, cached customer history shown from 10:42, Submit disabled until connection returns, and Retry connection. |
| Bad UI | A generic Try again button appears after every error, including validation and permission failures users cannot fix by repeating the request. | Tiny transient toast for a blocking failure. | A blank page shows a large spinner with no text, no affected object, and no idea what is loading. | A blank page says You are offline even though the app has cached drafts and help content. |
| Good UX | A user retries the same export after a network timeout, sees the attempt change to sending, and then returns to the recovered download state without re-entering filters. | User input and filter context are preserved after failure, and retry returns to recovered content or a clear still-failed state. | After submit, users see payment PAY-2048 processing, can tell the button is temporarily unavailable, and then get either success or retry guidance. | A user loses connection while editing an inspection note, sees it saved on this device, attaches photos to a queue, and later watches the queue sync after reconnect. |
| Bad UX | The app retries aggressively every second during an outage and makes the service harder to recover. | Clearing work after save failure. | The spinner blocks the whole workspace for a small table refresh and prevents users from continuing other work. | The app keeps a spinner on Save during airplane mode and never explains that no network request can start. |
| Best fit | A load, save, submit, upload, export, sync, payment, or background request failed for a transient or uncertain reason. | A system or task failure blocks expected content or action. | A short action, request, save, submit, refresh, sync, or fetch is actively processing and progress cannot be meaningfully measured. | Connection loss or server reachability changes the user's current task. |
| Avoid when | The error is caused by invalid user input and correction is required. | Nothing exists yet and the state is expected. | The content layout is predictable and a skeleton would better preserve structure. | A single request failed while the rest of the app is reachable and an error state is clearer. |
| Required state | Retryable failed state with affected operation, object, and preserved request context. | Normal expected state before failure. | Idle state with no spinner and the action or region ready. | Online normal state with no offline warning. |
| Accessibility burden | Use an action label that names the operation, not only an icon or generic phrase. | Use appropriate alert or status semantics for newly appearing critical errors. | Give the spinner or affected region an accessible name that identifies the operation. | Announce significant connectivity changes with status messaging when they affect the current task. |
| Common misuse | Offering Retry for every error regardless of whether the user or system state can change. | Using a transient toast for critical errors. | Showing an unlabeled spinner on a blank page. | Showing only a browser-style offline page when useful cached or local content exists. |