-
-
Notifications
You must be signed in to change notification settings - Fork 7
Open
Labels
Description
🔧 Refactor
Problem
The codebase has multiple inconsistent error handling patterns across different components and API layers, making it difficult to maintain, debug, and provide consistent user experience.
Current Error Handling Patterns Analysis
✅ GOOD PATTERNS (Established Standards)
1. Comprehensive API Error Handling (itemFunctions.ts)
const handleApiOperation = async (operation, toastId, successMessage) => {
try {
const data = await operation()
toast.update(toastId, {
render: successMessage,
type: 'success',
isLoading: false,
autoClose: 5000,
})
return { success: true, data }
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error)
toast.update(toastId, {
render: errorMessage,
type: 'error',
isLoading: false,
autoClose: 5000,
closeButton: true,
})
return { success: false }
}
}2. Authentication with toast.promise Pattern
// LoginPage.tsx, SignupPage.tsx, RequestPasswordPage.tsx
await toast.promise(login({ email, password }), {
success: { render({ data }) { return `Hi ${data?.first_name}` } },
error: { render({ data }) { return `${data as string}` } },
pending: 'logging in ...',
})3. Structured Error State Management (App.tsx)
const [loading, setLoading] = useState<boolean>(true)
const [error, setError] = useState<string | null>(null)
catch (error: any) {
console.error('Failed to load map:', error)
setError(
typeof error === 'string' ? error :
(error?.errors?.length > 0 ? error.errors[0]?.message : null) ||
error?.message ||
'Failed to connect to the server. Please check your connection and try again.'
)
setLoading(false)
}❌ PROBLEMATIC PATTERNS (Inconsistent)
1. Silent Failures (Geographic Search)
// SearchControl.tsx
catch (error) {
console.log(error) // Only logging, no user feedback
}
// ReverseGeocoder.ts
catch (error) {
console.error('Error:', error) // Only logging
return '' // Silent failure
}2. Inconsistent Toast Error Handling
// ItemViewPopup.tsx
catch (error) {
toast.error(error.toString()) // Basic toString()
}
// ItemFormPopup.tsx
catch (error) {
toast.error(error instanceof Error ? error.message : String(error)) // Better
}
// SocialShareBar.tsx
catch (error: never) {
toast.error('Fehler beim Kopieren des Links: ', error) // Mixed language
}3. Inconsistent API Error Processing
// itemsApi.ts - Good pattern
catch (error: any) {
console.error(error)
if (error.errors?.[0]?.message) {
throw new Error(error.errors[0].message)
} else {
throw error
}
}
// userApi.ts - Different pattern
catch (error: any) {
console.log(error) // console.log vs console.error
if (error.errors[0]?.message) throw error.errors[0].message
else throw error
}
// refiBcnApi.ts - Another pattern
catch (error: any) {
console.log(error)
if (error.errors[0]?.message) throw error.errors[0].message
else throw error
}4. Missing Error Boundaries
- No React Error Boundaries found in the codebase
- No fallback UI for component crashes
- No error recovery mechanisms for rendering errors
5. Inconsistent Loading State Management
// Some components use local loading state
const [loading, setLoading] = useState<boolean>(false)
// Others use toast.loading with manual updates
const toastId = toast.loading('Creating profile at location')
// Others use toast.promise (best practice)
await toast.promise(operation(), { pending, success, error })6. Form Validation Inconsistencies
// Basic validation in ItemFormPopup.tsx
if (!itemName) {
toast.error('Name must be defined')
return false
}
// HTML validation in TextInput.tsx
<input required={required} pattern={pattern} />
// No centralized validation utilitiesImpact on Codebase
Maintainability Issues
- Code Duplication: Similar error handling logic repeated across files
- Inconsistent Debugging: Different logging patterns make issues harder to trace
- Mixed Standards: New developers unsure which pattern to follow
User Experience Issues
- Inconsistent Feedback: Some errors show toasts, others fail silently
- Mixed Languages: Error messages in different languages
- No Recovery Options: Users can't retry failed operations consistently
Development Issues
- Testing Complexity: Different error patterns require different test approaches
- Error Tracking: Inconsistent error reporting makes monitoring difficult
- Onboarding Friction: New developers need to learn multiple patterns
Refactoring Goals
1. Standardize Error Handling Utilities
- Create reusable error handling functions
- Establish consistent logging patterns
- Implement standard error message formatting
2. Implement Error Boundaries
- Add React Error Boundaries for component crash recovery
- Create fallback UI components
- Implement error reporting mechanisms
3. Unify Loading State Patterns
- Standardize on
toast.promisefor async operations - Create consistent loading state management
- Implement proper loading indicators
4. Centralize Form Validation
- Create reusable validation utilities
- Implement consistent validation error display
- Add proper form error recovery
Refactoring Plan
Phase 1: Create Standard Utilities
// utils/errorHandling.ts
export const handleApiError = (error: unknown): string => {
if (error instanceof Error) return error.message
if (typeof error === 'string') return error
if (error?.errors?.[0]?.message) return error.errors[0].message
return 'An unexpected error occurred'
}
export const logError = (context: string, error: unknown) => {
console.error(`[${context}]`, error)
// Add error reporting service integration
}Phase 2: Implement Error Boundaries
// components/ErrorBoundary.tsx
class ErrorBoundary extends React.Component {
// Standard error boundary implementation
}Phase 3: Standardize Existing Patterns
- Update all API classes to use consistent error handling
- Replace silent failures with proper user feedback
- Unify toast notification patterns
Reactions are currently unavailable