378 lines
9.5 KiB
Markdown
378 lines
9.5 KiB
Markdown
# 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 |