Skip to content

[Polish] Error handling — private profiles, API downtime, graceful degradation #20

@grovecj

Description

@grovecj

Summary

Implement comprehensive error handling across the application for all known failure modes.

Details

Error Scenarios

Scenario Backend Behavior Frontend Display
Player not found 404 with { error: "player_not_found" } "No player found" with search suggestions
Private profile 403 with { error: "private_profile" } "This player's profile is private" with instructions to change privacy settings
CoD API down 503 with { error: "api_unavailable" } + serve stale cache if available "Stats temporarily unavailable" + show cached data with staleness warning
SSO token expired 503 with { error: "token_expired" } "Stats service is temporarily unavailable, please try again later" (generic message — this is an admin-side issue, not user-facing)
Rate limited 429 with retry-after header "Too many requests, please wait" with countdown
Squad not found 404 "Squad not found or has been deleted"
Network error N/A (frontend-only) "Unable to connect to server" with retry button

Admin Token Monitoring

  • GET /api/v1/health should include token status (valid/expired) in the response for admin monitoring
  • POST /api/v1/admin/token allows refreshing the SSO token without restarting the server (secured by ADMIN_API_KEY)
  • When token expires, the admin is responsible for refreshing it — users just see a generic "temporarily unavailable" message

Backend Error Response Format

{
  "error": "error_code",
  "message": "Human-readable description",
  "details": {},       // Optional additional context
  "cached": true,      // If serving stale cached data
  "cachedAt": "..."    // When the cached data was fetched
}

Frontend Error Components

Error/
├── ErrorBanner.vue      // Dismissable warning banner (for stale data)
├── ErrorPage.vue        // Full-page error (404, 503)
├── ErrorInline.vue      // Inline error within a component
└── RetryButton.vue      // Retry action with cooldown

Global Error Handling

  • Axios response interceptor for common error codes
  • Pinia useAppStore tracks global error/warning state
  • Toast notifications for transient errors
  • Banner for persistent warnings (stale data)

Acceptance Criteria

  • All error scenarios produce appropriate HTTP status codes
  • Frontend displays user-friendly messages for each error type
  • Token expired errors shown as generic "temporarily unavailable" to users (not auth-related messaging)
  • Health endpoint includes token validity status for admin monitoring
  • Stale cached data served with visual warning during API outage
  • Retry mechanism available for transient failures
  • No raw error messages or stack traces exposed to users

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions