- Create LayoutPreviewPage component for full-screen layout previews - Add preview route /themes/:themeId/layouts/:layoutId/preview to App routing - Update theme components with preview links and improved navigation - Fix iframe sandbox error by adding allow-scripts permission - Enhance template renderer with layout metadata support - Replace PostCSS with regex-only CSS parsing for browser compatibility - Add comprehensive standards documentation for code quality - Clean up CSS slot indicators to be always visible with descriptions 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
240 lines
6.1 KiB
Markdown
240 lines
6.1 KiB
Markdown
# Error Handling Standards
|
|
|
|
## Current State: INCONSISTENT
|
|
Error handling varies across the codebase - some functions have comprehensive error handling while others are missing it entirely.
|
|
|
|
## Required Error Handling Patterns
|
|
|
|
### 1. Error Boundaries (MISSING)
|
|
Implement React error boundaries for component-level error handling:
|
|
|
|
```typescript
|
|
// ✅ IMPLEMENT - ThemeErrorBoundary.tsx
|
|
import React, { Component, ErrorInfo, ReactNode } from 'react';
|
|
|
|
interface Props {
|
|
children: ReactNode;
|
|
fallback?: ReactNode;
|
|
}
|
|
|
|
interface State {
|
|
hasError: boolean;
|
|
error?: Error;
|
|
}
|
|
|
|
export class ThemeErrorBoundary extends Component<Props, State> {
|
|
constructor(props: Props) {
|
|
super(props);
|
|
this.state = { hasError: false };
|
|
}
|
|
|
|
static getDerivedStateFromError(error: Error): State {
|
|
return { hasError: true, error };
|
|
}
|
|
|
|
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
|
|
console.error('Theme component error:', error, errorInfo);
|
|
// Log to error reporting service in production
|
|
}
|
|
|
|
render() {
|
|
if (this.state.hasError) {
|
|
return this.props.fallback || (
|
|
<div className="error-fallback">
|
|
<h2>Something went wrong</h2>
|
|
<p>There was an error loading the theme system.</p>
|
|
<button onClick={() => window.location.reload()}>
|
|
Reload Page
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return this.props.children;
|
|
}
|
|
}
|
|
```
|
|
|
|
### 2. Async Error Handling (STANDARDIZE)
|
|
Consistent pattern for all async operations:
|
|
|
|
```typescript
|
|
// ✅ STANDARD PATTERN
|
|
const performAsyncOperation = async (id: string) => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
const result = await riskyOperation(id);
|
|
|
|
if (!result) {
|
|
throw new Error(`Operation failed for ${id}`);
|
|
}
|
|
|
|
return result;
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
setError(message);
|
|
console.error(`Async operation failed:`, error);
|
|
throw error; // Re-throw if caller needs to handle
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
```
|
|
|
|
### 3. Hook Error Handling (IMPLEMENT)
|
|
Custom hook for consistent error states:
|
|
|
|
```typescript
|
|
// ✅ IMPLEMENT - useAsyncOperation.ts
|
|
import { useState, useCallback } from 'react';
|
|
|
|
interface AsyncState<T> {
|
|
data: T | null;
|
|
loading: boolean;
|
|
error: string | null;
|
|
}
|
|
|
|
export function useAsyncOperation<T>() {
|
|
const [state, setState] = useState<AsyncState<T>>({
|
|
data: null,
|
|
loading: false,
|
|
error: null
|
|
});
|
|
|
|
const execute = useCallback(async (operation: () => Promise<T>) => {
|
|
setState(prev => ({ ...prev, loading: true, error: null }));
|
|
|
|
try {
|
|
const data = await operation();
|
|
setState({ data, loading: false, error: null });
|
|
return data;
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : 'Operation failed';
|
|
setState(prev => ({ ...prev, loading: false, error: message }));
|
|
throw error;
|
|
}
|
|
}, []);
|
|
|
|
return { ...state, execute };
|
|
}
|
|
```
|
|
|
|
### 4. Network Error Handling (ENHANCE)
|
|
Standardized fetch error handling:
|
|
|
|
```typescript
|
|
// ✅ STANDARD PATTERN
|
|
const fetchWithErrorHandling = async (url: string, options?: RequestInit) => {
|
|
try {
|
|
const response = await fetch(url, options);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
}
|
|
|
|
return response;
|
|
} catch (error) {
|
|
if (error instanceof TypeError) {
|
|
throw new Error('Network error - check your connection');
|
|
}
|
|
throw error;
|
|
}
|
|
};
|
|
```
|
|
|
|
## Error Types & Classifications
|
|
|
|
### 1. User Errors (Recoverable)
|
|
- Invalid theme selection
|
|
- Missing form data
|
|
- File upload issues
|
|
**Handling**: Show user-friendly message, allow retry
|
|
|
|
### 2. System Errors (Technical)
|
|
- Network failures
|
|
- Parse errors
|
|
- Configuration issues
|
|
**Handling**: Log details, show generic message, provide fallback
|
|
|
|
### 3. Critical Errors (Unrecoverable)
|
|
- Dependency failures
|
|
- Memory issues
|
|
- Corrupt data
|
|
**Handling**: Error boundary, full page reload option
|
|
|
|
## Logging Standards
|
|
|
|
### Development
|
|
```typescript
|
|
// ✅ PATTERN
|
|
console.group(`🔥 ${operation} Error`);
|
|
console.error('Details:', error);
|
|
console.error('Context:', context);
|
|
console.groupEnd();
|
|
```
|
|
|
|
### Production
|
|
```typescript
|
|
// ✅ PATTERN (when error service added)
|
|
errorReportingService.captureException(error, {
|
|
context,
|
|
user: getCurrentUser(),
|
|
timestamp: new Date().toISOString()
|
|
});
|
|
```
|
|
|
|
## Error Message Standards
|
|
|
|
### User-Facing Messages
|
|
- **Clear & Actionable**: "Could not load theme. Please try again."
|
|
- **No technical jargon**: Avoid error codes, stack traces
|
|
- **Suggest solutions**: "Check your connection and retry"
|
|
|
|
### Developer Messages
|
|
- **Detailed context**: Include operation, parameters, state
|
|
- **Stack traces**: Preserve for debugging
|
|
- **Structured data**: Consistent error object format
|
|
|
|
## Implementation Checklist
|
|
|
|
### HIGH PRIORITY
|
|
- [ ] Add ThemeErrorBoundary to App.tsx
|
|
- [ ] Implement useAsyncOperation hook
|
|
- [ ] Standardize theme loading error handling
|
|
- [ ] Add network error handling to fetch operations
|
|
|
|
### MEDIUM PRIORITY
|
|
- [ ] Create error fallback components
|
|
- [ ] Add error recovery mechanisms (retry buttons)
|
|
- [ ] Implement error state consistency across components
|
|
- [ ] Add loading state management standards
|
|
|
|
### LOW PRIORITY
|
|
- [ ] Add error reporting service integration
|
|
- [ ] Implement error analytics tracking
|
|
- [ ] Add error rate monitoring
|
|
- [ ] Create error handling documentation
|
|
|
|
## Testing Requirements
|
|
- **Error boundary testing**: Verify fallback rendering
|
|
- **Async error testing**: Test network failures, timeouts
|
|
- **Recovery testing**: Ensure retry mechanisms work
|
|
- **Error state testing**: Verify error messages display correctly
|
|
|
|
## Current Problem Areas
|
|
|
|
### Missing Error Boundaries
|
|
No React error boundaries implemented - component errors crash the app
|
|
|
|
### Inconsistent Async Patterns
|
|
Some async operations handle errors, others don't:
|
|
- `themeLoader.ts` ✅ Has good error handling
|
|
- Some components ❌ Missing error handling
|
|
|
|
### No Error Recovery
|
|
Users cannot recover from errors - no retry buttons or reload options
|
|
|
|
### Logging Inconsistency
|
|
Mix of `console.warn`, `console.error`, and no logging |