# H4 Error Boundaries Implementation Plan for 50-Dollar-App

## Current Status

✅ **Root Error Boundary Exists**: `/src/app/error.tsx` - A well-designed error boundary is already in place at the root level with:
- Professional UI with card layout
- Development mode error messages
- User-friendly support information
- Retry and homepage navigation options
- Responsive design

❌ **Missing Nested Error Boundaries**: No error boundaries in specific route segments

## Gap Analysis

### What's Missing:
1. **Global Error Boundary** - For server-side rendering errors
2. **Auth Section Error Boundary** - For authentication-related errors
3. **Authenticated Section Error Boundary** - For dashboard/post-auth errors
4. **Dynamic Route Error Boundaries** - For specific conversation/job pages
5. **API Error Boundary Wrapper** - For consistent API error handling

### Current Error Handling Patterns:
- API routes use try-catch with specific error responses
- Client components use useState for error management
- No error boundaries for server components
- No consistent error recovery mechanism

## Implementation Plan

### 1. Global Error Boundary
**File**: `src/app/global-error.tsx`
**Purpose**: Catch errors during server-side rendering and server components

```tsx
'use client'

import { useEffect } from 'react'
import { AlertCircle, RefreshCw, Home } from 'lucide-react'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'

export default function GlobalError({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  useEffect(() => {
    console.error('Global error:', error)
  }, [error])

  return (
    <html lang="en-AU">
      <body>
        <div className="min-h-screen bg-background flex items-center justify-center p-4">
          <div className="w-full max-w-md">
            <Card className="border-destructive/20">
              <CardHeader className="text-center">
                <div className="mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-destructive/10">
                  <AlertCircle className="h-6 w-6 text-destructive" />
                </div>
                <CardTitle className="text-xl">System Error</CardTitle>
                <CardDescription className="mt-2">
                  Something went wrong while loading the page.
                </CardDescription>
              </CardHeader>
              
              <CardContent>
                {process.env.NODE_ENV === 'development' && (
                  <div className="rounded-lg bg-muted p-4 mb-4">
                    <p className="text-sm font-mono text-muted-foreground">
                      {error.message || 'Unknown error occurred'}
                    </p>
                    {error.digest && (
                      <p className="mt-2 text-xs text-muted-foreground">
                        Error ID: {error.digest}
                      </p>
                    )}
                  </div>
                )}
              </CardContent>
              
              <CardFooter className="flex flex-col gap-3">
                <Button onClick={reset} className="w-full">
                  <RefreshCw className="mr-2 h-4 w-4" />
                  Try again
                </Button>
                <Button 
                  onClick={() => window.location.href = '/'} 
                  className="w-full"
                  variant="outline"
                >
                  <Home className="mr-2 h-4 w-4" />
                  Go to homepage
                </Button>
              </CardFooter>
            </Card>
          </div>
        </div>
      </body>
    </html>
  )
}
```

### 2. Auth Section Error Boundary
**File**: `src/app/auth/error.tsx`
**Purpose**: Handle errors in authentication flow

```tsx
'use client'

import { useEffect } from 'react'
import Link from 'next/link'
import { AlertCircle, RefreshCw, Home, LogIn } from 'lucide-react'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'

export default function AuthError({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  useEffect(() => {
    console.error('Auth section error:', error)
  }, [error])

  return (
    <div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100 flex items-center justify-center p-4">
      <div className="w-full max-w-md">
        <Card className="border-destructive/20">
          <CardHeader className="text-center">
            <div className="mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-destructive/10">
              <AlertCircle className="h-6 w-6 text-destructive" />
            </div>
            <CardTitle className="text-xl">Authentication Error</CardTitle>
            <CardDescription className="mt-2">
              We couldn't complete your authentication.
            </CardDescription>
          </CardHeader>
          
          <CardContent className="space-y-4">
            {process.env.NODE_ENV === 'development' && (
              <div className="rounded-lg bg-muted p-4">
                <p className="text-sm font-mono text-muted-foreground">
                  {error.message || 'Unknown error occurred'}
                </p>
              </div>
            )}
            
            <div className="rounded-lg bg-accent/50 p-4">
              <p className="text-sm text-accent-foreground">
                Try clearing your browser cookies or contact support if the problem persists.
              </p>
            </div>
          </CardContent>
          
          <CardFooter className="flex flex-col gap-3">
            <Button onClick={reset} className="w-full">
              <RefreshCw className="mr-2 h-4 w-4" />
              Try again
            </Button>
            
            <div className="grid grid-cols-2 gap-3 w-full">
              <Button asChild variant="outline" className="w-full">
                <Link href="/auth/login">
                  <LogIn className="mr-2 h-4 w-4" />
                  Login
                </Link>
              </Button>
              
              <Button asChild variant="outline" className="w-full">
                <Link href="/">
                  <Home className="mr-2 h-4 w-4" />
                  Home
                </Link>
              </Button>
            </div>
          </CardFooter>
        </Card>
      </div>
    </div>
  )
}
```

### 3. Authenticated Section Error Boundary
**File**: `src/app/(authenticated)/error.tsx`
**Purpose**: Handle errors in authenticated dashboard area

```tsx
'use client'

import { useEffect } from 'react'
import Link from 'next/link'
import { AlertCircle, RefreshCw, Home, LayoutDashboard } from 'lucide-react'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'
import { BottomNavWrapper } from '@/components/bottom-nav-wrapper'

export default function AuthenticatedError({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  useEffect(() => {
    console.error('Authenticated section error:', error)
  }, [error])

  return (
    <div className="min-h-screen bg-background pb-20">
      <header className="sticky top-0 z-50 border-b bg-background/95 backdrop-blur">
        <div className="mx-auto flex h-16 max-w-screen-sm items-center justify-between px-4">
          <Link href="/dashboard" className="text-xl font-bold tracking-tight">
            RateRight
          </Link>
          <Link href="/dashboard">
            <Button variant="ghost" size="sm">
              <LayoutDashboard className="mr-2 h-4 w-4" />
              Dashboard
            </Button>
          </Link>
        </div>
      </header>

      <main className="mx-auto max-w-screen-sm px-4 py-12">
        <Card className="border-destructive/20">
          <CardHeader className="text-center">
            <div className="mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-destructive/10">
              <AlertCircle className="h-6 w-6 text-destructive" />
            </div>
            <CardTitle className="text-xl">Dashboard Error</CardTitle>
            <CardDescription className="mt-2">
              Something went wrong with your dashboard.
            </CardDescription>
          </CardHeader>
          
          <CardContent className="space-y-4">
            {process.env.NODE_ENV === 'development' && (
              <div className="rounded-lg bg-muted p-4">
                <p className="text-sm font-mono text-muted-foreground">
                  {error.message || 'Unknown error occurred'}
                </p>
                {error.digest && (
                  <p className="mt-2 text-xs text-muted-foreground">
                    Error ID: {error.digest}
                  </p>
                )}
              </div>
            )}
            
            <div className="rounded-lg bg-accent/50 p-4">
              <p className="text-sm text-accent-foreground">
                Don't worry, your data is safe. Try refreshing the page or contact support if the issue persists.
              </p>
            </div>
          </CardContent>
          
          <CardFooter className="flex flex-col gap-3">
            <Button onClick={reset} className="w-full">
              <RefreshCw className="mr-2 h-4 w-4" />
              Try again
            </Button>
            
            <Button asChild variant="outline" className="w-full">
              <Link href="/dashboard">
                <Home className="mr-2 h-4 w-4" />
                Go to Dashboard
              </Link>
            </Button>
          </CardFooter>
        </Card>
      </main>

      <BottomNavWrapper userType="worker" />
    </div>
  )
}
```

### 4. Dynamic Route Error Boundaries

#### Conversation Error Boundary
**File**: `src/app/(authenticated)/messages/[conversationId]/error.tsx`
**Purpose**: Handle errors in conversation pages

```tsx
'use client'

import { useEffect } from 'react'
import Link from 'next/link'
import { useParams } from 'next/navigation'
import { AlertCircle, RefreshCw, MessageSquare, ArrowLeft } from 'lucide-react'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'

export default function ConversationError({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  const params = useParams()
  const conversationId = params?.conversationId

  useEffect(() => {
    console.error(`Conversation error for ${conversationId}:`, error)
  }, [error, conversationId])

  return (
    <div className="flex-1 flex items-center justify-center bg-gray-50 p-4">
      <Card className="border-destructive/20 max-w-md w-full">
        <CardHeader className="text-center">
          <div className="mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-destructive/10">
            <AlertCircle className="h-6 w-6 text-destructive" />
          </div>
          <CardTitle className="text-xl">Conversation Error</CardTitle>
          <CardDescription className="mt-2">
            We couldn't load this conversation.
          </CardDescription>
        </CardHeader>
        
        <CardContent className="space-y-4">
          {process.env.NODE_ENV === 'development' && (
            <div className="rounded-lg bg-muted p-4">
              <p className="text-sm font-mono text-muted-foreground">
                {error.message || 'Unknown error occurred'}
              </p>
              {error.digest && (
                <p className="mt-2 text-xs text-muted-foreground">
                  Error ID: {error.digest}
                </p>
              )}
            </div>
          )}
          
          <div className="rounded-lg bg-accent/50 p-4">
            <p className="text-sm text-accent-foreground">
              This conversation may have been deleted or you don't have access to it.
            </p>
          </div>
        </CardContent>
        
        <CardFooter className="flex flex-col gap-3">
          <Button onClick={reset} className="w-full">
            <RefreshCw className="mr-2 h-4 w-4" />
            Try again
          </Button>
          
          <div className="grid grid-cols-2 gap-3 w-full">
            <Button asChild variant="outline" className="w-full">
              <Link href="/messages">
                <MessageSquare className="mr-2 h-4 w-4" />
                All Messages
              </Link>
            </Button>
            
            <Button asChild variant="outline" className="w-full">
              <Link href="/dashboard">
                <ArrowLeft className="mr-2 h-4 w-4" />
                Dashboard
              </Link>
            </Button>
          </div>
        </CardFooter>
      </Card>
    </div>
  )
}
```

### 5. API Error Handler Utility
**File**: `src/lib/api-error-handler.ts`
**Purpose**: Standardize API error responses

```ts
import { NextResponse } from 'next/server';

export interface APIError {
  message: string;
  code?: string;
  details?: any;
}

export class APIErrorHandler {
  static badRequest(message: string, details?: any) {
    return NextResponse.json(
      { error: { message, code: 'BAD_REQUEST', details } },
      { status: 400 }
    );
  }

  static unauthorized(message: string = 'Unauthorized') {
    return NextResponse.json(
      { error: { message, code: 'UNAUTHORIZED' } },
      { status: 401 }
    );
  }

  static forbidden(message: string = 'Forbidden') {
    return NextResponse.json(
      { error: { message, code: 'FORBIDDEN' } },
      { status: 403 }
    );
  }

  static notFound(message: string = 'Not found') {
    return NextResponse.json(
      { error: { message, code: 'NOT_FOUND' } },
      { status: 404 }
    );
  }

  static rateLimited(retryAfter?: number) {
    const headers = retryAfter ? { 'Retry-After': retryAfter.toString() } : {};
    return NextResponse.json(
      { error: { message: 'Too many requests', code: 'RATE_LIMITED', retryAfter } },
      { status: 429, headers }
    );
  }

  static internal(message: string = 'Internal server error') {
    return NextResponse.json(
      { error: { message, code: 'INTERNAL_ERROR' } },
      { status: 500 }
    );
  }
}

export function withErrorHandler(handler: Function) {
  return async (...args: any[]) => {
    try {
      return await handler(...args);
    } catch (error) {
      console.error('API Route Error:', error);
      
      if (error instanceof Error) {
        return APIErrorHandler.internal(error.message);
      }
      
      return APIErrorHandler.internal();
    }
  };
}
```

### 6. Error Monitoring Service
**File**: `src/lib/error-monitoring.ts`
**Purpose**: Centralized error logging and reporting

```ts
interface ErrorPayload {
  message: string;
  stack?: string;
  component?: string;
  route?: string;
  userId?: string;
  metadata?: Record<string, any>;
  timestamp: string;
}

export class ErrorMonitoring {
  private static async logError(payload: ErrorPayload) {
    // Log to console in development
    if (process.env.NODE_ENV === 'development') {
      console.error('Error logged:', payload);
      return;
    }

    // In production, send to your error tracking service
    try {
      // Example: Send to Supabase error_logs table
      const { getSupabaseAdmin } = await import('@/lib/supabase/server');
      const supabase = getSupabaseAdmin();
      
      await supabase.from('error_logs').insert({
        message: payload.message,
        stack_trace: payload.stack,
        component: payload.component,
        route: payload.route,
        user_id: payload.userId,
        metadata: payload.metadata,
        created_at: payload.timestamp,
      });
    } catch (e) {
      console.error('Failed to log error:', e);
    }
  }

  static logClientError(error: Error, component?: string, metadata?: Record<string, any>) {
    const payload: ErrorPayload = {
      message: error.message,
      stack: error.stack,
      component,
      route: typeof window !== 'undefined' ? window.location.pathname : undefined,
      timestamp: new Date().toISOString(),
      metadata,
    };

    this.logError(payload);
  }

  static logServerError(error: Error, route?: string, userId?: string, metadata?: Record<string, any>) {
    const payload: ErrorPayload = {
      message: error.message,
      stack: error.stack,
      route,
      userId,
      timestamp: new Date().toISOString(),
      metadata,
    };

    this.logError(payload);
  }
}
```

## Implementation Steps

### Phase 1: Core Error Boundaries (Priority 1)
1. Create `global-error.tsx` for server-side errors
2. Create `auth/error.tsx` for authentication errors
3. Create `(authenticated)/error.tsx` for dashboard errors

### Phase 2: Specific Route Errors (Priority 2)
1. Create `messages/[conversationId]/error.tsx` for conversation errors
2. Create `contractor/post-job/error.tsx` for job posting errors
3. Create `worker/jobs/error.tsx` for job browsing errors

### Phase 3: Error Handling Improvements (Priority 3)
1. Implement `api-error-handler.ts` utility
2. Update API routes to use standardized error responses
3. Add error monitoring service
4. Create error boundary wrapper for client components

### Phase 4: Testing & Monitoring (Priority 4)
1. Add error boundary testing utilities
2. Implement error tracking in production
3. Set up alerts for critical errors
4. Create error analytics dashboard

## Testing Strategy

### Development Testing
```tsx
// Test error boundary with throw button
export function ErrorBoundaryTest() {
  const [shouldThrow, setShouldThrow] = useState(false)
  
  if (shouldThrow) {
    throw new Error('Test error for boundary')
  }
  
  return (
    <Button onClick={() => setShouldThrow(true)}>
      Test Error Boundary
    </Button>
  )
}
```

### Production Monitoring
- Log all errors to Supabase
- Set up alerts for error spikes
- Monitor error rates by route
- Track user impact

## Benefits

1. **Better User Experience**: Users see friendly error pages instead of blank screens
2. **Error Recovery**: Users can retry or navigate to safety
3. **Debugging**: Development mode shows error details
4. **Monitoring**: Centralized error tracking for improvements
5. **Stability**: Prevents cascade failures in the app

## Next Steps

1. Implement Phase 1 error boundaries immediately
2. Add error monitoring to track issues in production
3. Create a dashboard to monitor error rates
4. Train team on error boundary best practices