# Contributing to RateRight

Thank you for your interest in contributing to RateRight! This guide will help you understand our error handling patterns and coding standards.

## Error Handling Philosophy

At RateRight, we believe in **graceful error handling** that provides clear feedback to users while maintaining security and debugging capabilities. Our approach balances three key principles:

1. **User Experience**: Users should understand what went wrong and what they can do about it
2. **Security**: Never expose sensitive information or implementation details
3. **Debugging**: Developers need enough information to fix issues quickly

## Error Handling Patterns

### API Routes (`src/app/api/**/route.ts`)

**Standard Pattern:**
```typescript
import { NextResponse } from 'next/server';
import { logger } from '@/lib/logger';
import { HTTP_STATUS_INTERNAL_SERVER_ERROR } from '@/lib/constants';

export async function POST(request: NextRequest) {
  try {
    // Validate input
    const body = await request.json();
    if (!body.requiredField) {
      return NextResponse.json(
        { error: 'Missing required field: requiredField' },
        { status: 400 }
      );
    }
    
    // Process request
    const result = await processRequest(body);
    
    return NextResponse.json({ data: result });
    
  } catch (error) {
    logger.error('Descriptive error context:', error);
    
    // Handle specific error types
    if (error instanceof Error && error.message.includes('Stripe')) {
      return NextResponse.json(
        { error: 'Payment service unavailable' },
        { status: 503 }
      );
    }
    
    // Generic error response
    return NextResponse.json(
      { error: 'Internal server error' },
      { status: HTTP_STATUS_INTERNAL_SERVER_ERROR }
    );
  }
}
```

**Key Rules:**
- Always use try-catch blocks in route handlers
- Return appropriate HTTP status codes (400, 401, 403, 404, 500, 503)
- Log errors with context using `logger.error()`
- Return user-friendly error messages, never raw error objects
- Handle specific error types with appropriate status codes

### Client Components (`src/app/**/page.tsx`, `src/components/**/*.tsx`)

**Standard Pattern:**
```typescript
'use client';

import { useState } from 'react';
import toast from 'react-hot-toast';

export default function MyComponent() {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  
  async function handleSubmit() {
    setLoading(true);
    setError(null);
    
    try {
      const response = await fetch('/api/my-endpoint', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ data: 'value' })
      });
      
      const result = await response.json();
      
      if (!response.ok) {
        // Handle API errors
        throw new Error(result.error || 'Request failed');
      }
      
      // Success
      toast.success('Operation completed successfully!');
      
    } catch (error) {
      // Handle network errors and other exceptions
      const message = error instanceof Error ? error.message : 'Something went wrong';
      
      // Show user-friendly error message
      toast.error(message);
      
      // Set local error state for form display
      setError(message);
      
    } finally {
      setLoading(false);
    }
  }
  
  return (
    <div>
      {error && (
        <div className="rounded-lg bg-destructive/10 p-3 mb-4">
          <p className="text-sm text-destructive font-medium">{error}</p>
        </div>
      )}
      {/* Component content */}
    </div>
  );
}
```

**Key Rules:**
- Use `toast.error()` for user-facing error notifications
- Use local error state for form-level error display
- Always handle network errors and JSON parsing errors
- Provide specific, actionable error messages
- Reset error state when retrying operations

### Server Functions and Utilities (`src/lib/**/*.ts`)

**Standard Pattern:**
```typescript
import { logger } from '@/lib/logger';

export async function serverUtilityFunction(params: Params): Promise<Result> {
  try {
    // Validate parameters
    if (!params.requiredParam) {
      throw new Error('Missing required parameter: requiredParam');
    }
    
    // Process
    const result = await processData(params);
    
    return result;
    
  } catch (error) {
    logger.error('Context about what failed:', error);
    
    // Re-throw for caller to handle, or handle specific cases
    if (error instanceof Error && error.message.includes('specific condition')) {
      // Handle specific error case
      throw new Error('User-friendly error message');
    }
    
    // Re-throw original error or wrap with context
    throw error;
  }
}
```

**Key Rules:**
- Log errors with context using `logger.error()`
- Throw errors to be handled by callers
- Provide meaningful error messages
- Validate parameters and throw early

### Error Boundaries and Global Error Handling

**Error Component Pattern:**
```typescript
'use client';

import { useEffect } from 'react';
import { logger } from '@/lib/logger';
import { ErrorDisplay } from '@/components/error-display';

export default function ErrorBoundary({
  error,
  reset,
}: {
  error: Error & { digest?: string };
  reset: () => void;
}) {
  useEffect(() => {
    logger.error('Component error:', error);
  }, [error]);

  return (
    <ErrorDisplay
      title="Something went wrong"
      message="We encountered an unexpected error. Please try again."
      error={error}
      onRetry={reset}
      onGoHome={() => window.location.href = '/'}
    />
  );
}
```

## Error Message Guidelines

### DO:
- ✅ Be specific about what went wrong
- ✅ Suggest how to fix the issue
- ✅ Use friendly, non-technical language
- ✅ Keep error messages concise
- ✅ Log detailed errors for debugging

### DON'T:
- ❌ Expose internal error details or stack traces
- ❌ Use technical jargon users won't understand
- ❌ Show generic "Something went wrong" without context
- ❌ Log sensitive information (passwords, tokens, etc.)

## Common Error Scenarios

### Authentication Errors
```typescript
// Good
return NextResponse.json(
  { error: 'Invalid email or password' },
  { status: 401 }
);

// Bad
return NextResponse.json(
  { error: 'Auth failed: user not found in database' },
  { status: 401 }
);
```

### Validation Errors
```typescript
// Good
return NextResponse.json(
  { error: 'Email address is required' },
  { status: 400 }
);

// Bad
return NextResponse.json(
  { error: 'Validation failed' },
  { status: 400 }
);
```

### Rate Limiting Errors
```typescript
// Good
return NextResponse.json(
  { error: 'Too many requests. Please try again later.' },
  { status: 429 }
);

// Bad
return NextResponse.json(
  { error: 'Rate limit exceeded' },
  { status: 429 }
);
```

## Logging Guidelines

### Use `logger.error()` for:
- Server-side errors in API routes
- Critical application errors
- Errors that need debugging context

### Use `console.error()` for:
- Temporary debugging (remove before committing)
- Development-only error tracking

### Never log:
- Passwords or authentication tokens
- Personal user information
- Full error stack traces in production

## Testing Error Handling

Always test your error handling:

1. **Network failures**: Test with network disconnected
2. **Invalid input**: Test with malformed data
3. **Authentication**: Test with expired/invalid tokens
4. **Rate limiting**: Test rapid repeated requests
5. **Server errors**: Test with backend services down

## Code Review Checklist

When reviewing code, ensure:

- [ ] All API routes have try-catch blocks
- [ ] Client components handle fetch errors properly
- [ ] User-facing errors are friendly and actionable
- [ ] Sensitive information is not exposed in error messages
- [ ] Errors are logged with appropriate context
- [ ] Error states are properly reset on retry
- [ ] Loading states are handled correctly during errors

## Migration from Inconsistent Patterns

If you encounter existing code with inconsistent error handling:

1. **Document the current pattern** in your PR description
2. **Follow the existing pattern** in that file/module for consistency
3. **Create an issue** to standardize the pattern later
4. **Don't mix patterns** within the same file or module

## Getting Help

If you're unsure about error handling patterns:

1. Check existing code in similar files
2. Ask in the team chat or create a discussion
3. Follow the principle of "graceful degradation"
4. When in doubt, log the error and show a user-friendly message

---

Thank you for helping make RateRight more robust and user-friendly! 🚀