dev setup
This commit is contained in:
378
apps/website/docs/API_ERROR_HANDLING.md
Normal file
378
apps/website/docs/API_ERROR_HANDLING.md
Normal file
@@ -0,0 +1,378 @@
|
||||
# API Error Handling & Resilience System
|
||||
|
||||
This document describes the comprehensive error handling infrastructure added to the GridPilot website to handle API connectivity issues, request errors, and provide graceful degradation.
|
||||
|
||||
## Overview
|
||||
|
||||
The system provides:
|
||||
- **Enhanced error classification** with detailed error types
|
||||
- **Automatic retry logic** with exponential backoff
|
||||
- **Circuit breaker pattern** to prevent cascading failures
|
||||
- **Connection health monitoring** with real-time status
|
||||
- **User-friendly error messages** for production
|
||||
- **Developer-friendly debugging tools** for development
|
||||
- **Graceful degradation** with fallbacks and caching
|
||||
- **Offline mode detection**
|
||||
|
||||
## Core Components
|
||||
|
||||
### 1. Enhanced Error Classification (`ApiError`)
|
||||
|
||||
**Location:** `lib/api/base/ApiError.ts`
|
||||
|
||||
**Error Types:**
|
||||
- `NETWORK_ERROR` - Connection failed, CORS issues
|
||||
- `AUTH_ERROR` - 401/403 authentication issues
|
||||
- `VALIDATION_ERROR` - 400 bad request
|
||||
- `NOT_FOUND` - 404 resource not found
|
||||
- `SERVER_ERROR` - 500+ server issues
|
||||
- `RATE_LIMIT_ERROR` - 429 too many requests
|
||||
- `TIMEOUT_ERROR` - Request timeout
|
||||
- `CANCELED_ERROR` - Request aborted
|
||||
|
||||
**Features:**
|
||||
- Automatic error type classification
|
||||
- User-friendly vs developer-friendly messages
|
||||
- Retry capability detection
|
||||
- Connectivity issue detection
|
||||
- Severity levels for logging
|
||||
|
||||
### 2. Retry Handler & Circuit Breaker (`RetryHandler.ts`)
|
||||
|
||||
**Location:** `lib/api/base/RetryHandler.ts`
|
||||
|
||||
**Retry Logic:**
|
||||
- Exponential backoff with jitter
|
||||
- Configurable max retries (default: 3)
|
||||
- Configurable timeout (default: 30s)
|
||||
- Abort support for cancellation
|
||||
|
||||
**Circuit Breaker:**
|
||||
- Tracks failures per endpoint
|
||||
- Opens after threshold (default: 5 failures)
|
||||
- Half-open state for recovery testing
|
||||
- Automatic reset after timeout
|
||||
|
||||
### 3. Connection Monitor (`ApiConnectionMonitor.ts`)
|
||||
|
||||
**Location:** `lib/api/base/ApiConnectionMonitor.ts`
|
||||
|
||||
**Features:**
|
||||
- Real-time connection status tracking
|
||||
- Health check polling (every 30s)
|
||||
- Reliability percentage calculation
|
||||
- Event emitter for status changes
|
||||
- Request/response time tracking
|
||||
|
||||
**Statuses:**
|
||||
- `connected` - Healthy API
|
||||
- `degraded` - Reduced reliability
|
||||
- `disconnected` - Unavailable
|
||||
- `checking` - Health check in progress
|
||||
|
||||
### 4. Enhanced BaseApiClient (`BaseApiClient.ts`)
|
||||
|
||||
**Location:** `lib/api/base/BaseApiClient.ts`
|
||||
|
||||
**Enhancements:**
|
||||
- Automatic error classification
|
||||
- Retry logic integration
|
||||
- Circuit breaker usage
|
||||
- Connection monitoring
|
||||
- Timeout handling
|
||||
- Request cancellation
|
||||
|
||||
**Usage:**
|
||||
```typescript
|
||||
const client = new BaseApiClient(
|
||||
baseUrl,
|
||||
errorReporter,
|
||||
logger,
|
||||
{ timeout: 30000, retry: true }
|
||||
);
|
||||
|
||||
// All methods now support retry and graceful degradation
|
||||
const data = await client.get('/api/endpoint');
|
||||
```
|
||||
|
||||
### 5. Error UI Components
|
||||
|
||||
**Location:** `components/errors/`
|
||||
|
||||
**Components:**
|
||||
- `ErrorDisplay.tsx` - User-friendly error screen
|
||||
- `DevErrorPanel.tsx` - Developer debugging panel
|
||||
- `ApiErrorBoundary.tsx` - React error boundary
|
||||
- `ApiStatusToolbar.tsx` - Real-time status toolbar
|
||||
- `NotificationIntegration.tsx` - Notification system integration
|
||||
|
||||
### 6. Graceful Degradation (`GracefulDegradation.ts`)
|
||||
|
||||
**Location:** `lib/api/base/GracefulDegradation.ts`
|
||||
|
||||
**Features:**
|
||||
- Response caching with TTL
|
||||
- Fallback data support
|
||||
- Offline mode detection
|
||||
- Service wrapper for easy usage
|
||||
|
||||
**Usage:**
|
||||
```typescript
|
||||
import { withGracefulDegradation, GracefulService } from './GracefulDegradation';
|
||||
|
||||
// Direct usage
|
||||
const data = await withGracefulDegradation(
|
||||
() => apiClient.getData(),
|
||||
{
|
||||
fallback: defaultData,
|
||||
timeout: 5000,
|
||||
useCache: true
|
||||
}
|
||||
);
|
||||
|
||||
// Service wrapper
|
||||
const userService = new GracefulService(
|
||||
'user-data',
|
||||
() => apiClient.getUser(),
|
||||
defaultUser
|
||||
);
|
||||
|
||||
const user = await userService.get();
|
||||
```
|
||||
|
||||
### 7. Enhanced Error Reporter (`EnhancedErrorReporter.ts`)
|
||||
|
||||
**Location:** `lib/infrastructure/EnhancedErrorReporter.ts`
|
||||
|
||||
**Features:**
|
||||
- Environment-specific handling
|
||||
- User notification integration
|
||||
- Error buffering for batch reporting
|
||||
- Custom error handlers
|
||||
- External service integration (placeholder)
|
||||
|
||||
## Integration in Application
|
||||
|
||||
### Layout Integration
|
||||
|
||||
```tsx
|
||||
// apps/website/app/layout.tsx
|
||||
|
||||
import { NotificationIntegration } from '@/components/errors/NotificationIntegration';
|
||||
import { ApiErrorBoundary } from '@/components/errors/ApiErrorBoundary';
|
||||
import { ApiStatusToolbar } from '@/components/errors/ApiStatusToolbar';
|
||||
|
||||
export default function RootLayout({ children }) {
|
||||
return (
|
||||
<html>
|
||||
<body>
|
||||
<NotificationProvider>
|
||||
<NotificationIntegration />
|
||||
<ApiErrorBoundary>
|
||||
{/* Your app content */}
|
||||
{children}
|
||||
|
||||
{/* Development toolbar */}
|
||||
{process.env.NODE_ENV === 'development' && (
|
||||
<ApiStatusToolbar position="bottom-right" autoHide={true} />
|
||||
)}
|
||||
</ApiErrorBoundary>
|
||||
</NotificationProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Service Integration
|
||||
|
||||
```typescript
|
||||
// lib/services/DriverService.ts
|
||||
|
||||
import { BaseApiClient } from '@/lib/api/base/BaseApiClient';
|
||||
import { EnhancedErrorReporter } from '@/lib/infrastructure/EnhancedErrorReporter';
|
||||
import { ConsoleLogger } from '@/lib/infrastructure/ConsoleLogger';
|
||||
|
||||
// Enhanced service with error handling
|
||||
export class DriverService {
|
||||
private apiClient: BaseApiClient;
|
||||
private errorReporter: EnhancedErrorReporter;
|
||||
|
||||
constructor() {
|
||||
const logger = new ConsoleLogger();
|
||||
this.errorReporter = new EnhancedErrorReporter(logger, {
|
||||
showUserNotifications: true,
|
||||
logToConsole: true,
|
||||
reportToExternal: process.env.NODE_ENV === 'production',
|
||||
});
|
||||
|
||||
this.apiClient = new BaseApiClient(
|
||||
getWebsiteApiBaseUrl(),
|
||||
this.errorReporter,
|
||||
logger,
|
||||
{ timeout: 30000, retry: true }
|
||||
);
|
||||
}
|
||||
|
||||
async getDriverProfile(driverId: string): Promise<DriverProfileViewModel | null> {
|
||||
try {
|
||||
const dto = await this.apiClient.getDriverProfile(driverId);
|
||||
return new DriverProfileViewModel(dto);
|
||||
} catch (error) {
|
||||
// Error already handled by BaseApiClient
|
||||
// Return null for graceful degradation
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Development Tools
|
||||
|
||||
### DevToolbar Integration
|
||||
|
||||
The enhanced DevToolbar includes:
|
||||
- Real-time API status indicator
|
||||
- Reliability percentage
|
||||
- Circuit breaker status
|
||||
- Health check button
|
||||
- Stats reset
|
||||
- Test error trigger
|
||||
|
||||
### ApiStatusToolbar
|
||||
|
||||
A floating toolbar that shows:
|
||||
- Current connection status
|
||||
- Request statistics
|
||||
- Circuit breaker states
|
||||
- Quick actions for testing
|
||||
|
||||
## Error Handling Patterns
|
||||
|
||||
### 1. Automatic Retry
|
||||
```typescript
|
||||
// Automatically retries failed requests
|
||||
const data = await client.get('/api/data');
|
||||
```
|
||||
|
||||
### 2. Graceful Fallback
|
||||
```typescript
|
||||
const data = await withGracefulDegradation(
|
||||
() => client.get('/api/data'),
|
||||
{ fallback: defaultData }
|
||||
);
|
||||
```
|
||||
|
||||
### 3. Error Boundary
|
||||
```typescript
|
||||
<ApiErrorBoundary>
|
||||
<MyComponent />
|
||||
</ApiErrorBoundary>
|
||||
```
|
||||
|
||||
### 4. Manual Error Handling
|
||||
```typescript
|
||||
try {
|
||||
const data = await client.get('/api/data');
|
||||
} catch (error) {
|
||||
if (isApiError(error)) {
|
||||
if (error.isRetryable()) {
|
||||
// Show retry button
|
||||
}
|
||||
if (error.isConnectivityIssue()) {
|
||||
// Show connection error
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Environment-Specific Behavior
|
||||
|
||||
### Development
|
||||
- Detailed error messages with stack traces
|
||||
- Developer error panel with full context
|
||||
- API status toolbar always visible
|
||||
- Console logging with full details
|
||||
- Test error triggers
|
||||
|
||||
### Production
|
||||
- User-friendly error messages
|
||||
- Modal notifications for critical errors
|
||||
- Toast notifications for warnings
|
||||
- No sensitive data in error messages
|
||||
- Automatic error reporting to external services
|
||||
|
||||
## Monitoring & Debugging
|
||||
|
||||
### Connection Health
|
||||
```typescript
|
||||
import { connectionMonitor } from '@/lib/api/base/ApiConnectionMonitor';
|
||||
|
||||
// Get current status
|
||||
const status = connectionMonitor.getStatus();
|
||||
|
||||
// Get detailed health
|
||||
const health = connectionMonitor.getHealth();
|
||||
|
||||
// Run manual health check
|
||||
const result = await connectionMonitor.performHealthCheck();
|
||||
```
|
||||
|
||||
### Circuit Breaker Status
|
||||
```typescript
|
||||
import { CircuitBreakerRegistry } from '@/lib/api/base/RetryHandler';
|
||||
|
||||
const registry = CircuitBreakerRegistry.getInstance();
|
||||
const status = registry.getStatus();
|
||||
```
|
||||
|
||||
### Error Buffer
|
||||
```typescript
|
||||
import { getGlobalErrorReporter } from '@/lib/infrastructure/EnhancedErrorReporter';
|
||||
|
||||
const reporter = getGlobalErrorReporter();
|
||||
const errors = reporter.getBufferedErrors();
|
||||
reporter.flush(); // Send batch
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Always use BaseApiClient** for API calls
|
||||
2. **Wrap critical components** with ApiErrorBoundary
|
||||
3. **Provide fallbacks** for graceful degradation
|
||||
4. **Use error classification** for specific handling
|
||||
5. **Monitor connection status** for user feedback
|
||||
6. **Test error scenarios** in development
|
||||
7. **Log appropriately** based on severity
|
||||
8. **Use caching** for frequently accessed data
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### API Always Shows "Disconnected"
|
||||
- Check API_BASE_URL environment variable
|
||||
- Verify CORS configuration on API server
|
||||
- Check browser console for network errors
|
||||
- Use DevToolbar health check
|
||||
|
||||
### Requests Not Retrying
|
||||
- Verify retry option is enabled in BaseApiClient
|
||||
- Check error type is retryable
|
||||
- Review circuit breaker status
|
||||
|
||||
### Notifications Not Showing
|
||||
- Ensure NotificationProvider wraps your app
|
||||
- Check NotificationIntegration is mounted
|
||||
- Verify error severity levels
|
||||
|
||||
### Circuit Breaker Stays Open
|
||||
- Check API server health
|
||||
- Reset circuit breakers via DevToolbar
|
||||
- Review error logs for root cause
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
- External error reporting (Sentry, LogRocket)
|
||||
- Persistent cache storage (IndexedDB)
|
||||
- Offline queue for failed requests
|
||||
- Performance metrics dashboard
|
||||
- A/B testing for error recovery strategies
|
||||
Reference in New Issue
Block a user