Summary
Improve error handling to match SOVD GenericError format and add resilience features for unreliable connections.
Proposed solution
1. SOVD GenericError Handling
Gateway returns errors in SOVD-compliant format:
{
"error_code": "ERR_RESOURCE_NOT_FOUND",
"message": "Component not found",
"parameters": {
"entity_id": "unknown_component",
"entity_type": "component"
}
}
Create typed error handling:
interface SovdError {
error_code: string;
message: string;
parameters?: Record<string, unknown>;
}
class ApiError extends Error {
constructor(
public readonly status: number,
public readonly sovdError: SovdError
) {
super(sovdError.message);
}
}
// Error code mapping for user-friendly messages
const ERROR_MESSAGES: Record<string, string> = {
'ERR_RESOURCE_NOT_FOUND': 'The requested resource was not found',
'ERR_INVALID_REQUEST': 'Invalid request parameters',
'ERR_SERVICE_UNAVAILABLE': 'Service temporarily unavailable',
'ERR_UNAUTHORIZED': 'Authentication required',
'ERR_FORBIDDEN': 'Access denied',
// ...
};
2. Retry Logic with Exponential Backoff
async function fetchWithRetry<T>(
fn: () => Promise<T>,
options: {
maxRetries?: number;
baseDelay?: number;
maxDelay?: number;
retryOn?: (error: Error) => boolean;
} = {}
): Promise<T> {
const { maxRetries = 3, baseDelay = 1000, maxDelay = 10000 } = options;
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
if (attempt === maxRetries) throw error;
const delay = Math.min(baseDelay * 2 ** attempt, maxDelay);
await new Promise(r => setTimeout(r, delay));
}
}
throw new Error('Unreachable');
}
3. Connection State Management
interface ConnectionState {
status: 'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'error';
lastConnected: Date | null;
reconnectAttempts: number;
error: string | null;
}
// Auto-reconnect on connection loss
// Exponential backoff for reconnection attempts
// Visual indicator in header showing connection state
4. Offline Support (Optional PWA)
- Cache entity tree structure for offline viewing
- Queue write operations when offline
- Sync when back online
- Service worker for caching static assets
5. Error Boundaries
// App-level error boundary
function AppErrorBoundary({ children }: { children: React.ReactNode }) {
return (
<ErrorBoundary
fallback={<AppCrashScreen />}
onError={(error) => {
// Log to monitoring service
console.error('App crashed:', error);
}}
>
{children}
</ErrorBoundary>
);
}
// Panel-level error boundary with retry
function PanelErrorBoundary({ children }: { children: React.ReactNode }) {
return (
<ErrorBoundary
fallback={({ resetErrorBoundary }) => (
<ErrorPanel onRetry={resetErrorBoundary} />
)}
>
{children}
</ErrorBoundary>
);
}
Additional context
Error handling priorities:
- User sees clear, actionable error messages
- Transient errors auto-retry without user action
- Connection issues show reconnection status
- App never fully crashes - graceful degradation
Summary
Improve error handling to match SOVD GenericError format and add resilience features for unreliable connections.
Proposed solution
1. SOVD GenericError Handling
Gateway returns errors in SOVD-compliant format:
{ "error_code": "ERR_RESOURCE_NOT_FOUND", "message": "Component not found", "parameters": { "entity_id": "unknown_component", "entity_type": "component" } }Create typed error handling:
2. Retry Logic with Exponential Backoff
3. Connection State Management
4. Offline Support (Optional PWA)
5. Error Boundaries
Additional context
Error handling priorities: