We use cookies to enhance your experience on the site
CodeWorlds

Error Boundaries - Guards of Your Application

Error Boundaries are special React components that act like safety systems on a space station. When one module fails, the Error Boundary isolates the problem and prevents the entire station from being destroyed.

What Are Error Boundaries?

An Error Boundary is a class component in React that catches JavaScript errors anywhere in its child component tree, logs them, and displays a fallback UI instead of the tree that crashed.

Two Key Methods

An Error Boundary is a class component that implements one or both of these methods:

  1. static getDerivedStateFromError(error)
    - Updates state so the next render shows a fallback UI
  2. componentDidCatch(error, errorInfo)
    - Logs error information (e.g., to a monitoring service)

Basic Implementation

1import React from 'react';
2
3class ErrorBoundary extends React.Component {
4  constructor(props) {
5    super(props);
6    this.state = { hasError: false, error: null };
7  }
8
9  // Called when a child component throws an error
10  // Returns an object that updates the state
11  static getDerivedStateFromError(error) {
12    return { hasError: true, error: error };
13  }
14
15  // Called after catching an error
16  // Great place for logging errors
17  componentDidCatch(error, errorInfo) {
18    console.error('Error caught:', error);
19    console.error('Component stack:', errorInfo.componentStack);
20  }
21
22  render() {
23    if (this.state.hasError) {
24      return (
25        <div className="error-fallback">
26          <h2>Something went wrong!</h2>
27          <p>{this.state.error?.message}</p>
28        </div>
29      );
30    }
31
32    return this.props.children;
33  }
34}

Using Error Boundaries

An Error Boundary wraps the components you want to protect:

1function SpaceStation() {
2  return (
3    <div className="station">
4      <ErrorBoundary>
5        <Navigation />
6      </ErrorBoundary>
7
8      <ErrorBoundary>
9        <MainPanel />
10      </ErrorBoundary>
11
12      <ErrorBoundary>
13        <StatusBar />
14      </ErrorBoundary>
15    </div>
16  );
17}

Now if

MainPanel
throws an error,
Navigation
and
StatusBar
will still work!

Error Boundary Granularity

You can use different levels of granularity:

Application Level (general safety net)

1function App() {
2  return (
3    <ErrorBoundary fallback={<h1>Entire station failure!</h1>}>
4      <SpaceStation />
5    </ErrorBoundary>
6  );
7}

Section Level (module isolation)

1function SpaceStation() {
2  return (
3    <div>
4      <ErrorBoundary fallback={<p>Navigation offline</p>}>
5        <Navigation />
6      </ErrorBoundary>
7      <ErrorBoundary fallback={<p>Control panel unavailable</p>}>
8        <ControlPanel />
9      </ErrorBoundary>
10    </div>
11  );
12}

Component Level (precise isolation)

1function Dashboard() {
2  return (
3    <div className="dashboard">
4      {widgets.map(widget => (
5        <ErrorBoundary key={widget.id} fallback={<WidgetError />}>
6          <Widget data={widget} />
7        </ErrorBoundary>
8      ))}
9    </div>
10  );
11}

What Error Boundaries Do NOT Catch

It's important to know that Error Boundaries do not catch errors in:

  1. Event handlers - use
    try/catch
  2. Asynchronous code -
    setTimeout
    ,
    fetch
    , Promise
  3. Server-side rendering (SSR)
  4. Errors in the Error Boundary itself (not in its children)
1// Event handler - requires try/catch
2function Button() {
3  const handleClick = () => {
4    try {
5      riskyOperation();
6    } catch (err) {
7      // Handle the error here
8    }
9  };
10  return <button onClick={handleClick}>Click</button>;
11}

Custom Fallback with Props

The best practice is to create a reusable Error Boundary with a configurable fallback:

1class ErrorBoundary extends React.Component {
2  constructor(props) {
3    super(props);
4    this.state = { hasError: false, error: null };
5  }
6
7  static getDerivedStateFromError(error) {
8    return { hasError: true, error };
9  }
10
11  componentDidCatch(error, info) {
12    console.error('Error boundary caught:', error, info);
13  }
14
15  render() {
16    if (this.state.hasError) {
17      // Use the fallback prop if available
18      if (this.props.fallback) {
19        return this.props.fallback;
20      }
21      return <h2>An error occurred</h2>;
22    }
23    return this.props.children;
24  }
25}
26
27// Usage with custom fallback
28<ErrorBoundary fallback={<p>Module damaged, but the station is running!</p>}>
29  <RiskyModule />
30</ErrorBoundary>
Go to CodeWorlds