Lesson 25 — Error Boundaries (Advanced)

🧭 Introduction

No matter how carefully you write code, runtime errors happen:

  • API responses change
  • Unexpected undefined values 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

FeatureError Boundarytry/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

Leave a Comment