AI error states are handled with clear user messaging
Why it matters
AI API calls fail in distinct ways: rate limits (429), network drops, content policy blocks, and model-level errors. When these surface as a blank message, a raw JSON dump, or a generic toast with no retry path, users blame the product — not the underlying API. Per iso-25010:2011 reliability.fault-tolerance, the system must degrade gracefully. A rate-limit error that tells the user to wait 60 seconds retains trust; a silent failure causes churn. Distinguishing at least two error types is the minimum required to make error messaging actionable rather than decorative.
Severity rationale
High because undifferentiated error states leave users stranded — they cannot determine whether to retry, wait, rephrase, or escalate — directly degrading retention and support load.
Remediation
Replace catch-all error handling with a typed error classifier that produces distinct messages for rate limits, network failures, and content policy blocks. Render the message inline in the conversation thread, not as a dismissible toast.
const getErrorMessage = (error: Error): string => {
if (error.message.includes('429') || error.message.includes('rate limit'))
return "Rate limit reached — wait a moment and try again."
if (error.message.includes('content_policy'))
return "Response blocked by content policy. Try rephrasing."
if (error.message.includes('fetch') || error.message.includes('network'))
return "Connection issue — check your internet and retry."
return "Generation failed. Try again or regenerate."
}
{error && (
<div className="flex gap-2 p-3 rounded-lg bg-destructive/10 text-destructive text-sm">
<AlertCircleIcon className="w-4 h-4 mt-0.5 shrink-0" />
<span>{getErrorMessage(error)} <button onClick={reload} className="underline">Retry</button></span>
</div>
)}
Detection
-
ID:
error-state-handling -
Severity:
high -
What to look for: Count all AI API call sites (streaming endpoints, completion calls, generation requests). For each, enumerate the error handling:
try/catchblocks,.catch()handlers, or error state variables (error,isError,status === 'error'). Check whether errors are surfaced to the user with actionable messaging — not raw error objects dumped in the UI, but human-readable explanations. Enumerate the error types handled: rate limit (429), network, model, and content policy violations. At least 2 distinct error types should produce different messages. A generic catch-all "Something went wrong" with no retry guidance is NOT a pass — must not pass based on generic error handling alone. -
Pass criteria: AI generation errors are caught and display a human-readable message in the conversation UI. Different error types produce at least 2 different messages. Report: "X of Y API call sites have error handling; Z distinct error types handled."
-
Fail criteria: AI errors result in a blank response, a raw JSON error dump, a generic "Something went wrong" toast, or a console-only error with nothing shown to the user.
-
Skip (N/A) when: Same as
regeneration-button. -
Detail on fail:
"AI API errors caught in try/catch but UI shows only a generic toast with no action guidance. Rate limit errors and network errors are not distinguished.". -
Remediation: Error messages are trust moments. A clear, helpful error message builds confidence even when things go wrong.
const getErrorMessage = (error: Error): string => { if (error.message.includes('rate limit') || error.message.includes('429')) { return "You've reached the rate limit. Please wait a moment and try again." } if (error.message.includes('network') || error.message.includes('fetch')) { return "Connection issue — check your internet and try again." } if (error.message.includes('content_policy')) { return "This response was blocked by the content policy. Try rephrasing your message." } return "Something went wrong generating the response. Try regenerating." } {error && ( <div className="flex items-start gap-3 p-3 rounded-lg bg-destructive/10 text-destructive text-sm"> <AlertCircleIcon className="w-4 h-4 mt-0.5 shrink-0" /> <div> <p>{getErrorMessage(error)}</p> <button onClick={reload} className="underline mt-1">Try again</button> </div> </div> )}
External references
- iso-25010:2011 · reliability.fault-tolerance — Fault Tolerance — system operates as intended when AI API errors occur
Taxons
History
- 2026-04-18·v1.0.0·Initial import from ai-ux-patterns·automated