Skip to content

feat(reliability): timeout, retry button, reduced-motion dots#33

Merged
PAMulligan merged 1 commit into
mainfrom
12-typing-indicator-retry-timeout-graceful-degradation
May 8, 2026
Merged

feat(reliability): timeout, retry button, reduced-motion dots#33
PAMulligan merged 1 commit into
mainfrom
12-typing-indicator-retry-timeout-graceful-degradation

Conversation

@PAMulligan
Copy link
Copy Markdown
Contributor

Summary

  • Per-attempt request timeout via AbortController (default 30s, configurable via requestTimeoutMs; pass 0 to disable). Aborts surface as a retryable ChatApiError with code: "TIMEOUT".
  • useChat now exposes retry() + canRetry. retry() re-sends the same message array without duplicating the user turn. canRetry is false for validation/config errors and true for timeouts, network failures, rate limits, and 5xx.
  • Inline Retry button next to the error pill, hidden while loading.
  • Typing dots switched to motion-safe:animate-bounce and given an aria-label so reduced-motion / SR users get a sane experience.
  • New i18n keys: errorTimeout, errorRetry, typingIndicator.
  • requestTimeoutMs exposed on ChatWidget, window.ClaudiusConfig, and <claudius-chat request-timeout-ms>.

Test plan

  • pnpm test (167/167 passing) — covers timeout abort, TIMEOUT retryability, retry-without-duplication, validation-error non-retry, and the Retry button render/click/hide states
  • pnpm exec tsc --noEmit clean
  • Manual: throttle network to Offline in DevTools, send a message, confirm error + Retry; come back online and click Retry
  • Manual: enable prefers-reduced-motion: reduce in OS settings and confirm typing dots stay static while still being visible

🤖 Generated with Claude Code

- Add per-attempt request timeout via AbortController (default 30s,
  configurable via requestTimeoutMs / request-timeout-ms / 0 to disable);
  surfaces a retryable ChatApiError with code TIMEOUT.
- Expose retry() and canRetry from useChat. retry() re-sends the existing
  message array without duplicating the user turn. canRetry is false for
  validation/config errors and true for timeouts, network failures, rate
  limits, and 5xx responses.
- Render an inline Retry button next to the error pill, hidden while
  loading.
- Switch typing-indicator dots to motion-safe:animate-bounce and add an
  aria-label so screen readers and reduced-motion users get the right UX.
- New i18n keys: errorTimeout, errorRetry, typingIndicator.
- Surface requestTimeoutMs through ChatWidget, window.ClaudiusConfig, and
  the <claudius-chat> web component.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@cloudflare-workers-and-pages
Copy link
Copy Markdown

Deploying chat-widget with  Cloudflare Pages  Cloudflare Pages

Latest commit: 4c9a2b4
Status: ✅  Deploy successful!
Preview URL: https://a1b50d74.chat-widget-ejc.pages.dev
Branch Preview URL: https://12-typing-indicator-retry-ti.chat-widget-ejc.pages.dev

View logs

@PAMulligan PAMulligan merged commit d87fdec into main May 8, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant