In this lesson, we'll explore advanced error handling techniques that you can apply in complex React applications. These patterns are like advanced safety systems on a space station - multi-layered, intelligent, and flexible.
In production, you need to know about errors immediately. Integrate Error Boundary with a monitoring system:
1class MonitoredErrorBoundary extends React.Component {
2 constructor(props) {
3 super(props);
4 this.state = { hasError: false, error: null, errorId: null };
5 }
6
7 static getDerivedStateFromError(error) {
8 return { hasError: true, error };
9 }
10
11 componentDidCatch(error, errorInfo) {
12 // Generate a unique error ID
13 const errorId = Date.now().toString(36);
14 this.setState({ errorId });
15
16 // Send to monitoring service
17 logErrorToService({
18 errorId,
19 message: error.message,
20 stack: error.stack,
21 componentStack: errorInfo.componentStack,
22 timestamp: new Date().toISOString(),
23 url: window.location.href,
24 userAgent: navigator.userAgent
25 });
26 }
27
28 render() {
29 if (this.state.hasError) {
30 return (
31 <div className="error-report">
32 <h3>An error occurred</h3>
33 <p>Error code: {this.state.errorId}</p>
34 <p>Our team has been notified.</p>
35 <button onClick={() => this.setState({ hasError: false })}>
36 Try again
37 </button>
38 </div>
39 );
40 }
41 return this.props.children;
42 }
43}Different parts of the application may require different error handling:
1import { createContext, useContext } from 'react';
2
3const ErrorContext = createContext({
4 onError: (error) => console.error(error),
5 severity: 'normal'
6});
7
8function useErrorHandler() {
9 const { onError, severity } = useContext(ErrorContext);
10
11 return (error) => {
12 if (severity === 'critical') {
13 // For critical sections - send an alert
14 sendAlert(error);
15 }
16 onError(error);
17 };
18}
19
20// Usage
21function CriticalSection({ children }) {
22 return (
23 <ErrorContext.Provider value={{
24 onError: (err) => sendToMonitoring(err),
25 severity: 'critical'
26 }}>
27 <ErrorBoundary>
28 {children}
29 </ErrorBoundary>
30 </ErrorContext.Provider>
31 );
32}1function AutoRecoveryBoundary({ children, maxRetries = 3 }) {
2 const [retryCount, setRetryCount] = useState(0);
3 const [key, setKey] = useState(0);
4
5 const handleReset = () => {
6 if (retryCount < maxRetries) {
7 setRetryCount(prev => prev + 1);
8 setKey(prev => prev + 1); // Forces remount
9 }
10 };
11
12 return (
13 <ErrorBoundary
14 key={key}
15 FallbackComponent={({ error }) => (
16 <div>
17 <p>Error: {error.message}</p>
18 {retryCount < maxRetries ? (
19 <button onClick={handleReset}>
20 Try again ({maxRetries - retryCount} attempts remaining)
21 </button>
22 ) : (
23 <p>Failed to fix the error. Contact support.</p>
24 )}
25 </div>
26 )}
27 >
28 {children}
29 </ErrorBoundary>
30 );
31}1function ChartWithFallback({ data }) {
2 return (
3 <ErrorBoundary
4 FallbackComponent={() => (
5 // Instead of an interactive chart, show a simple table
6 <table>
7 <thead><tr><th>Name</th><th>Value</th></tr></thead>
8 <tbody>
9 {data.map(item => (
10 <tr key={item.id}>
11 <td>{item.name}</td>
12 <td>{item.value}</td>
13 </tr>
14 ))}
15 </tbody>
16 </table>
17 )}
18 >
19 <InteractiveChart data={data} />
20 </ErrorBoundary>
21 );
22}Catch unhandled errors at the global level:
1// In the main application file
2useEffect(() => {
3 const handleUnhandledError = (event) => {
4 console.error('Unhandled error:', event.error);
5 // Send to monitoring
6 };
7
8 const handleUnhandledRejection = (event) => {
9 console.error('Unhandled promise rejection:', event.reason);
10 // Send to monitoring
11 };
12
13 window.addEventListener('error', handleUnhandledError);
14 window.addEventListener('unhandledrejection', handleUnhandledRejection);
15
16 return () => {
17 window.removeEventListener('error', handleUnhandledError);
18 window.removeEventListener('unhandledrejection', handleUnhandledRejection);
19 };
20}, []);| Pattern | When to Use | |---------|-------------| | Error Boundary | Component rendering errors | | try/catch | Event handlers and synchronous code | | useErrorBoundary | Asynchronous errors in Error Boundary | | Retry | Unstable network connections | | Fallback content | Optional data | | Global handler | Unexpected errors |