# ErrorDisplay Component API Design

**Date**: 2025-01-27  
**Action**: 3.1.1.1 - Design ErrorDisplay component API  
**Status**: ✅ Complete

## Overview

This document defines the API for a reusable `ErrorDisplay` component that standardizes error presentation across the application, replacing inconsistent toast notifications and inline error divs.

## Component Purpose

The `ErrorDisplay` component provides:

- **Consistent error UI** across the application
- **Contextual error information** (error type, message, details)
- **Recovery actions** (retry, dismiss, show details)
- **Accessibility** (ARIA labels, keyboard navigation)
- **Flexible placement** (inline, modal, banner)

## Component API

### Props Interface

```typescript
interface ErrorDisplayProps {
  /**
   * The error to display
   * Can be Error object, ApiError, string, or error-like object
   */
  error:
    | Error
    | ApiError
    | string
    | {
        message: string;
        code?: string | number;
        status?: number;
        details?: Record<string, any>;
      };

  /**
   * Callback when user clicks retry button
   * If not provided, retry button is hidden
   */
  onRetry?: () => void | Promise<void>;

  /**
   * Callback when user dismisses the error
   * If not provided, dismiss button is hidden
   */
  onDismiss?: () => void;

  /**
   * Whether to show detailed error information
   * Default: false (only shows user-friendly message)
   * In development, defaults to true
   */
  showDetails?: boolean;

  /**
   * Additional context about where/why the error occurred
   * Used for logging and debugging
   */
  context?: {
    action?: string; // e.g., "fetching tracks", "uploading file"
    resource?: string; // e.g., "tracks", "playlist"
    resourceId?: string; // e.g., track ID, playlist ID
    [key: string]: any; // Additional context
  };

  /**
   * Variant/style of error display
   * - "inline": Inline error within content (default)
   * - "banner": Full-width banner at top of page
   * - "modal": Modal dialog overlay
   * - "card": Card-style error display
   */
  variant?: 'inline' | 'banner' | 'modal' | 'card';

  /**
   * Error severity/category
   * Affects visual styling (color, icon)
   * - "error": Critical errors (default)
   * - "warning": Warnings that don't block functionality
   * - "info": Informational messages
   */
  severity?: 'error' | 'warning' | 'info';

  /**
   * Size of the error display
   * - "sm": Small, compact
   * - "md": Medium (default)
   * - "lg": Large, prominent
   */
  size?: 'sm' | 'md' | 'lg';

  /**
   * Custom className for styling
   */
  className?: string;

  /**
   * Whether error is dismissible
   * Default: true (if onDismiss provided)
   */
  dismissible?: boolean;

  /**
   * Custom title override
   * If not provided, uses default title based on error type
   */
  title?: string;

  /**
   * Custom icon override
   * If not provided, uses default icon based on severity
   */
  icon?: React.ReactNode;

  /**
   * Additional actions to display alongside retry/dismiss
   * Array of { label, onClick, variant } objects
   */
  actions?: Array<{
    label: string;
    onClick: () => void;
    variant?: 'default' | 'outline' | 'ghost';
  }>;
}
```

## Error Type Handling

### Error Object Normalization

The component normalizes different error types:

1. **Error Object**:

   ```typescript
   new Error('Failed to fetch tracks');
   ```

   - Message: `error.message`
   - Stack: Available in details (dev mode)

2. **ApiError** (from generated types):

   ```typescript
   { code: 404, message: 'Track not found', ... }
   ```

   - Message: `error.message`
   - Code: `error.code`
   - Status: `error.status`

3. **String**:

   ```typescript
   'Network error occurred';
   ```

   - Message: The string itself

4. **Axios Error**:

   ```typescript
   axiosError.response.data.error;
   ```

   - Extracts error message from response
   - Includes HTTP status code

## Default Behavior

### Error Message Extraction

1. **Priority order**:
   - `error.message` (if Error object)
   - `error.error?.message` (if ApiError)
   - `error.toString()` (fallback)
   - `String(error)` (final fallback)

2. **User-friendly messages**:
   - Maps technical error codes to user-friendly messages
   - Example: `ERR_NETWORK` → "Unable to connect to server. Please check your internet connection."

### Visual Styling

- **Error severity**: Red/error colors
- **Warning severity**: Yellow/warning colors
- **Info severity**: Blue/info colors

### Icons

- **Error**: `AlertTriangle` (red)
- **Warning**: `AlertCircle` (yellow)
- **Info**: `Info` (blue)

## Usage Examples

### Basic Inline Error

```typescript
<ErrorDisplay
  error={error}
  onRetry={() => refetch()}
/>
```

### Error with Context

```typescript
<ErrorDisplay
  error={error}
  context={{
    action: 'fetching tracks',
    resource: 'tracks',
  }}
  onRetry={handleRetry}
  showDetails={isDev}
/>
```

### Banner Error

```typescript
<ErrorDisplay
  error={error}
  variant="banner"
  onDismiss={() => setError(null)}
/>
```

### Modal Error

```typescript
<ErrorDisplay
  error={error}
  variant="modal"
  onRetry={handleRetry}
  onDismiss={() => setShowError(false)}
/>
```

### Error with Custom Actions

```typescript
<ErrorDisplay
  error={error}
  onRetry={handleRetry}
  actions={[
    {
      label: 'Report Issue',
      onClick: () => reportIssue(error),
      variant: 'outline',
    },
  ]}
/>
```

## Integration Points

### Replace Toast Errors

**Before**:

```typescript
toast.error('Failed to fetch tracks');
```

**After**:

```typescript
<ErrorDisplay
  error={error}
  variant="inline"
  onRetry={() => refetch()}
/>
```

### Replace Inline Error Divs

**Before**:

```typescript
{error && (
  <div className="text-red-500">{error.message}</div>
)}
```

**After**:

```typescript
{error && (
  <ErrorDisplay
    error={error}
    variant="inline"
    size="sm"
  />
)}
```

## Accessibility

- **ARIA labels**: `role="alert"`, `aria-live="polite"`
- **Keyboard navigation**: Tab to retry/dismiss buttons
- **Screen reader support**: Announces error message
- **Focus management**: Focuses retry button on mount

## Validation

✅ Component API designed  
✅ Props interface defined  
✅ Error type handling specified  
✅ Usage examples provided  
✅ Integration points identified  
⏭️ Next: Action 3.1.1.2 - Implement ErrorDisplay component
