🧭 Introduction
No matter how carefully you write code, runtime errors happen:
- API responses change
- Unexpected
undefinedvalues appear - Third-party libraries fail
- Edge cases slip into production
Without proper handling, a single error can:
❌ Crash the entire React app
❌ Show a blank screen to users
❌ Destroy user trust
To prevent this, React provides a powerful safety mechanism called:
Error Boundaries
This lesson teaches you how professional React applications fail gracefully instead of crashing.
🎯 What You’ll Learn in This Lesson
By the end of this lesson, you will understand:
- What error boundaries are
- What kinds of errors they catch
- How error boundaries work internally
- How to implement error boundaries
- Advanced patterns & best practices
- Common mistakes to avoid
🧠 What Are Error Boundaries?
Error Boundaries are React components that:
Catch JavaScript errors during rendering, in lifecycle methods, and in constructors of child components.
Instead of crashing the app, they:
- Log the error
- Display a fallback UI
❗ Important: What Error Boundaries Do NOT Catch
Error boundaries do not catch errors in:
- Event handlers
- Async code (setTimeout, promises)
- Server-side rendering
- Errors inside the error boundary itself
These must be handled separately.
🧩 Error Boundaries Are Class Components
As of now:
- Error boundaries must be class components
- Hooks cannot replace them (yet)
This is important for interviews and real projects.
🛠️ Basic Error Boundary Implementation
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, info) {
console.error("Error caught:", error, info);
}
render() {
if (this.state.hasError) {
return <h2>Something went wrong.</h2>;
}
return this.props.children;
}
}
🔍 How It Works Internally
1️⃣ A child component throws an error
2️⃣ React looks for nearest error boundary
3️⃣ getDerivedStateFromError updates state
4️⃣ componentDidCatch logs the error
5️⃣ Fallback UI is rendered
🧪 Using an Error Boundary
<ErrorBoundary>
<UserProfile />
</ErrorBoundary>
If UserProfile crashes:
✔ App does NOT crash
✔ Fallback UI is shown
🧠 Where Should You Place Error Boundaries?
❌ Bad Practice
Wrapping the entire app in one boundary only.
✅ Best Practice
Use multiple error boundaries:
- Around routes
- Around major features
- Around third-party components
Example
<ErrorBoundary>
<Dashboard />
</ErrorBoundary>
<ErrorBoundary>
<Settings />
</ErrorBoundary>
🧠 Error Boundary + Routing (Real Pattern)
<Route
path="/dashboard"
element={
<ErrorBoundary>
<Dashboard />
</ErrorBoundary>
}
/>
This isolates failures per route.
🧠 Custom Fallback UI (Professional UX)
Instead of plain text:
if (this.state.hasError) {
return (
<div>
<h2>Oops! Something broke 😔</h2>
<button onClick={() => window.location.reload()}>
Reload Page
</button>
</div>
);
}
User-friendly recovery matters.
🧠 Logging Errors (Production-Ready)
In real apps:
- Errors should be sent to monitoring tools
- Not just logged to console
componentDidCatch(error, info) {
logErrorToService(error, info);
}
Examples:
- Sentry
- LogRocket
- New Relic
❌ Common Mistakes
❌ Expecting Error Boundaries to Catch Async Errors
They won’t.
❌ Wrapping Everything Blindly
Use boundaries strategically.
❌ Showing Ugly Fallback UI
UX matters even during failure.
❌ Forgetting to Log Errors
Silent failures are dangerous.
🧠 Handling Errors NOT Caught by Boundaries
Event Handlers
try {
doSomething();
} catch (e) {
console.error(e);
}
Async Code
async function loadData() {
try {
await fetchData();
} catch (e) {
setError(e);
}
}
Error boundaries are not a replacement for try/catch.
🆚 Error Boundaries vs Try/Catch
| Feature | Error Boundary | try/catch |
|---|---|---|
| Render errors | ✅ Yes | ❌ No |
| Event errors | ❌ No | ✅ Yes |
| Async errors | ❌ No | ✅ Yes |
| UI fallback | ✅ Yes | ❌ No |
👉 Use both appropriately.
🎯 Best Practices (Senior-Level)
✅ Use multiple error boundaries
✅ Wrap risky components
✅ Provide meaningful fallback UI
✅ Log errors centrally
✅ Combine with async error handling
❓ FAQs — Error Boundaries
🔹 Are error boundaries mandatory?
No, but essential for production apps.
🔹 Can functional components be error boundaries?
No (currently).
🔹 Are error boundaries asked in interviews?
Yes — very frequently.
🔹 Can error boundaries replace try/catch?
No — they serve different purposes.
🧠 Quick Recap
✔ Error boundaries prevent app crashes
✔ Catch render & lifecycle errors
✔ Must be class components
✔ Use strategic placement
✔ Combine with async error handling
🎉 Conclusion
Error boundaries are the difference between:
❌ A crashing app
✅ A resilient application
They ensure your app:
- Fails gracefully
- Protects user experience
- Handles unexpected situations professionally
This lesson introduces a critical production-ready skill every advanced React developer must master 🛡️⚛️
👉 Next Lesson
Lesson 26 — Global Error Handling Strategies