DeployU
Interviews / Frontend Engineering / This component is crashing the entire app. Implement an Error Boundary to gracefully handle the error.

Questions

This component is crashing the entire app. Implement an Error Boundary to gracefully handle the error.

practical Debugging & Tools Interactive Quiz Code Examples

The Scenario

You’re working on a React application, and a specific component, BuggyComponent, is causing problems. Due to some unexpected data or a logical flaw, this component throws a JavaScript error during its render phase.

When this error occurs, it propagates up the component tree, causing the entire React application to unmount and display a blank screen. This is a terrible user experience and makes the application fragile.

The Challenge

Your task is to implement an Error Boundary.

  1. Wrap the BuggyComponent with your Error Boundary.
  2. The Error Boundary should catch the error thrown by BuggyComponent.
  3. Instead of crashing the whole application, it should display a user-friendly fallback message (e.g., “Something went wrong.”).
  4. It should also log the error to the console for debugging purposes.
Your Code
import React from 'react';

// This component will unconditionally throw an error during render.
function BuggyComponent() {
  // Simulate an error, e.g., trying to access a property of undefined
  throw new Error('I crashed!');
  // return <h1>I am a buggy component!</h1>; // This line will never be reached
}

// The main application component
export default function App() {
  return (
    <div>
      <h1>Welcome to the App!</h1>
      <p>Below is a component that might crash.</p>
      <BuggyComponent /> {/* This component will cause the app to crash */}
      <p>This text should still be visible if the error is handled.</p>
    </div>
  );
}
Click "Run Code" to see output...
Click "Run Code" to see test results...

The Explanation: Containing Errors with Error Boundaries

How Different Experience Levels Approach This
Junior Engineer
Surface Level

[object Object]

Senior Engineer
Production Ready

[object Object]

What Makes the Difference?
  • Context over facts: Explains when and why, not just what
  • Real examples: Provides specific use cases from production experience
  • Trade-offs: Acknowledges pros, cons, and decision factors

Understanding Error Boundaries

In React, errors in a component’s render method, lifecycle methods, or constructors will “bubble up” and unmount the entire component tree, leading to a blank screen. This is where Error Boundaries come in.

An Error Boundary is a special type of React component that catches JavaScript errors anywhere in its child component tree, logs those errors, and displays a fallback UI. They are implemented as class components and use two specific lifecycle methods:

  • static getDerivedStateFromError(error): This method is called after an error has been thrown by a descendant component. It should return a value to update state, allowing the next render to display a fallback UI.
  • componentDidCatch(error, info): This method is called after an error has been thrown. It’s used for side effects like logging the error information to an error reporting service.

The Fix: Implementing a Class-Based Error Boundary

Here is the corrected implementation:

import React, { Component } from 'react';

// The component that will unconditionally throw an error
function BuggyComponent() {
  throw new Error('I crashed!');
}

// The Error Boundary component
class ErrorBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  // This method is called after an error has been thrown by a descendant component.
  // It updates state so the next render will show the fallback UI.
  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  // This method is called after an error has been thrown.
  // It's used for side effects like logging the error.
  componentDidCatch(error, errorInfo) {
    console.error("Error caught by ErrorBoundary:", error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // Fallback UI when an error occurs
      return <h1>Something went wrong.</h1>;
    }

    // Render children normally if no error
    return this.props.children;
  }
}

// The main application component, now using the Error Boundary
export default function App() {
  return (
    <div>
      <h1>Welcome to the App!</h1>
      <p>Below is a component that might crash.</p>
      <ErrorBoundary> {/* Wrap the potentially buggy component */}
        <BuggyComponent />
      </ErrorBoundary>
      <p>This text should still be visible if the error is handled.</p>
    </div>
  );
}

By wrapping BuggyComponent with ErrorBoundary, any error thrown within BuggyComponent (or its children) will be caught by ErrorBoundary. The ErrorBoundary will then render its fallback UI, preventing the entire application from crashing and providing a better user experience.

Practice Question

What types of errors are React Error Boundaries designed to catch?