Garfish's error handling and fallback mechanisms ensure that micro-frontend applications can gracefully degrade when exceptions occur, providing a good user experience.
Error Handling Mechanisms
1. Sub-application Loading Errors
- Error Types: Network errors, resource loading failures, script execution errors
- Handling Strategies:
- Automatic retry mechanism
- Provide error messages
- Load fallback version
- Configuration Example:
javascript{ name: 'app1', entry: '//localhost:3001', errorBoundary: { onError: (error) => { console.error('Sub-application loading failed:', error); // Report error logs reportError(error); }, fallback: () => { // Display fallback page return <ErrorPage message="Application loading failed, please try again later" />; } } }
2. Runtime Errors
- Error Types: JavaScript runtime errors, component rendering errors
- Handling Strategies:
- Use error boundaries to catch
- Isolate error impact scope
- Provide error recovery mechanism
- Example:
javascript// React error boundary class ErrorBoundary extends React.Component { componentDidCatch(error, errorInfo) { // Catch sub-application errors Garfish.emit('app-error', { error, errorInfo }); } render() { if (this.state.hasError) { return <ErrorFallback />; } return this.props.children; } }
3. Lifecycle Errors
- Error Types: bootstrap, mount, unmount execution failures
- Handling Strategies:
- Catch lifecycle function errors
- Ensure proper resource cleanup
- Provide error callbacks
- Example:
javascriptexport async function mount(container) { try { ReactDOM.render(<App />, container); } catch (error) { // Clean up rendered content container.innerHTML = ''; throw error; } }
Fallback Strategies
1. Application-Level Fallback
- Strategy: Display fallback page when sub-application loading fails
- Implementation:
- Configure fallback component
- Display static content
- Provide retry button
- Example:
javascript{ name: 'app1', entry: '//localhost:3001', fallback: { component: () => ( <div className="fallback"> <h3>Application temporarily unavailable</h3> <button onClick={() => window.location.reload()}> Reload </button> </div> ) } }
2. Feature-Level Fallback
- Strategy: Degrade to simplified version when some features fail
- Implementation:
- Detect feature availability
- Provide alternative solutions
- Gradually restore features
- Example:
javascript// Check API availability async function checkApiAvailability() { try { await fetch('/api/health'); return true; } catch { return false; } } // Select implementation based on availability const Component = apiAvailable ? FullFeature : SimplifiedFeature;
3. Performance Fallback
- Strategy: Reduce feature complexity when performance is insufficient
- Implementation:
- Disable animation effects
- Reduce data loading
- Use simplified components
- Example:
javascript// Detect device performance const isLowPerformance = /low-performance/.test(navigator.userAgent); // Select component based on performance const AnimationComponent = isLowPerformance ? SimpleAnimation : FullAnimation;
Error Monitoring and Logging
1. Error Collection
- Collect error information from all sub-applications
- Record error context
- Standardize error format
2. Error Reporting
- Real-time error reporting to monitoring system
- Batch reporting to reduce network requests
- Support offline caching
3. Error Analysis
- Statistics on error frequency and types
- Analyze error impact scope
- Generate error reports
Best Practices
1. Error Prevention
- Comprehensive unit testing and integration testing
- Code review and quality checks
- Pre-release environment verification
2. Error Recovery
- Provide automatic retry mechanism
- Implement manual recovery options
- Save user state to avoid data loss
3. User Experience
- Friendly error messages
- Clear error explanations
- Provide solution suggestions
4. Monitoring and Alerts
- Set error threshold alerts
- Real-time error rate monitoring
- Quick response to critical errors
Through comprehensive error handling and fallback mechanisms, you can ensure the stability and reliability of micro-frontend applications.