Add comprehensive error handling and recovery UI #173

Merged
talksik merged 11 commits from claude/electron-error-handling-tPCJO into master 2026-04-21 02:22:02 +00:00
talksik commented 2026-04-17 02:41:03 +00:00 (Migrated from github.com)

Summary

Implements a complete error handling system with user-friendly recovery UI, including error boundaries at multiple levels, centralized error classification, and improved IPC error logging.

Key Changes

  • Error Boundaries: Added two-tier error boundary system:

    • TopLevelErrorBoundary catches crashes outside the router (bootstrap failures)
    • RouteErrorBoundary catches route-level crashes with automatic reset on navigation
    • Both boundaries report errors with contextual metadata (component stack, pathname, boundary type)
  • Error Classification & User Messages: Created @/lib/errors.ts with:

    • ApiError class for HTTP failures with status-aware messaging
    • QuotaExceededError for free-plan message limit exhaustion
    • toUserMessage() function that maps any error to user-friendly text
    • logError() and reportError() functions for different severity levels
  • Error Fallback UI: Implemented error-fallback.tsx with:

    • Unified error card component showing user message and icon
    • Dev-only technical details (stack trace) in collapsible section
    • "Go home" and "Try again" recovery actions
    • Separate implementations for top-level (hash navigation) and route-level (react-router) contexts
  • React Query Integration: Enhanced query-client.ts with:

    • Query cache error handler that logs and optionally toasts failures
    • Mutation cache error handler with suppressToast meta option for custom handling
    • Smart retry logic: transient errors (408, 429) retry once; 4xx errors don't retry
    • Mutations never auto-retry (side effects)
  • IPC Error Handling: Added main/ipc-utils.ts with:

    • safeHandle() wrapper that logs full stack traces in main process
    • Sanitizes errors before sending to renderer (prevents leaking internals)
    • Applied to screen:get-sources, app:get-version, and link:fetch-metadata handlers
  • Refactoring:

    • Moved ApiError from @/api/client.ts to @/lib/errors.ts (re-exported for back-compat)
    • Moved QuotaExceededError from @/hooks/use-create-particle.ts to @/lib/errors.ts (re-exported for back-compat)
    • Updated useCreateParticle to suppress global toast (compose UI handles custom quota UI)
    • Wrapped authenticated routes with RouteErrorBoundary
    • Wrapped app providers with TopLevelErrorBoundary
  • Improved Logging: Enhanced error logging in main.ts for link metadata fetching to track progressive enhancement failures

Notable Implementation Details

  • Error boundaries reset React Query's error cache on retry to prevent stale failures from persisting
  • Route error boundary automatically resets when pathname changes (clicking "Go home" clears the error)
  • IPC error handler logs full stack in main process but only sends sanitized message to renderer
  • User messages are environment-aware: dev shows technical details, prod shows friendly text only
  • Quota exceeded errors opt out of global mutation toast to avoid double-toasting with compose UI's custom prompt

https://claude.ai/code/session_013pwtbUwCLQdwpJJDShi9aL

## Summary Implements a complete error handling system with user-friendly recovery UI, including error boundaries at multiple levels, centralized error classification, and improved IPC error logging. ## Key Changes - **Error Boundaries**: Added two-tier error boundary system: - `TopLevelErrorBoundary` catches crashes outside the router (bootstrap failures) - `RouteErrorBoundary` catches route-level crashes with automatic reset on navigation - Both boundaries report errors with contextual metadata (component stack, pathname, boundary type) - **Error Classification & User Messages**: Created `@/lib/errors.ts` with: - `ApiError` class for HTTP failures with status-aware messaging - `QuotaExceededError` for free-plan message limit exhaustion - `toUserMessage()` function that maps any error to user-friendly text - `logError()` and `reportError()` functions for different severity levels - **Error Fallback UI**: Implemented `error-fallback.tsx` with: - Unified error card component showing user message and icon - Dev-only technical details (stack trace) in collapsible section - "Go home" and "Try again" recovery actions - Separate implementations for top-level (hash navigation) and route-level (react-router) contexts - **React Query Integration**: Enhanced `query-client.ts` with: - Query cache error handler that logs and optionally toasts failures - Mutation cache error handler with `suppressToast` meta option for custom handling - Smart retry logic: transient errors (408, 429) retry once; 4xx errors don't retry - Mutations never auto-retry (side effects) - **IPC Error Handling**: Added `main/ipc-utils.ts` with: - `safeHandle()` wrapper that logs full stack traces in main process - Sanitizes errors before sending to renderer (prevents leaking internals) - Applied to `screen:get-sources`, `app:get-version`, and `link:fetch-metadata` handlers - **Refactoring**: - Moved `ApiError` from `@/api/client.ts` to `@/lib/errors.ts` (re-exported for back-compat) - Moved `QuotaExceededError` from `@/hooks/use-create-particle.ts` to `@/lib/errors.ts` (re-exported for back-compat) - Updated `useCreateParticle` to suppress global toast (compose UI handles custom quota UI) - Wrapped authenticated routes with `RouteErrorBoundary` - Wrapped app providers with `TopLevelErrorBoundary` - **Improved Logging**: Enhanced error logging in `main.ts` for link metadata fetching to track progressive enhancement failures ## Notable Implementation Details - Error boundaries reset React Query's error cache on retry to prevent stale failures from persisting - Route error boundary automatically resets when pathname changes (clicking "Go home" clears the error) - IPC error handler logs full stack in main process but only sends sanitized message to renderer - User messages are environment-aware: dev shows technical details, prod shows friendly text only - Quota exceeded errors opt out of global mutation toast to avoid double-toasting with compose UI's custom prompt https://claude.ai/code/session_013pwtbUwCLQdwpJJDShi9aL
Sign in to join this conversation.