Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
FAQs Support
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials

Error Boundaries

What are Error Boundaries?

Error boundaries are React components that catch JavaScript errors in their child component tree, log them, and display a fallback UI instead of crashing the entire app. They work like a try-catch block for React components.

Error Boundaries — Class-based and react-error-boundary
import { Component } from 'react'

// Error boundaries MUST be class components (no hook equivalent yet)
class ErrorBoundary extends Component {
    constructor(props) {
        super(props)
        this.state = { hasError: false, error: null, errorInfo: null }
    }

    // Called when a descendant throws — update state to show fallback
    static getDerivedStateFromError(error) {
        return { hasError: true, error }
    }

    // Called after error is caught — good for logging
    componentDidCatch(error, errorInfo) {
        console.error('Error caught by boundary:', error)
        console.error('Component stack:', errorInfo.componentStack)

        // Log to error tracking service
        // Sentry.captureException(error, { extra: errorInfo })
        this.setState({ errorInfo })
    }

    render() {
        if (this.state.hasError) {
            // Custom fallback UI
            if (this.props.fallback) {
                return this.props.fallback
            }

            return (
                <div className="error-boundary">
                    <h2>Something went wrong</h2>
                    <p>{this.state.error?.message}</p>
                    {process.env.NODE_ENV === 'development' && (
                        <details>
                            <summary>Error details</summary>
                            <pre>{this.state.errorInfo?.componentStack}</pre>
                        </details>
                    )}
                    <button onClick={() => this.setState({ hasError: false, error: null })}>
                        Try Again
                    </button>
                </div>
            )
        }

        return this.props.children
    }
}

export default ErrorBoundary
// react-error-boundary — modern library (recommended)
// npm install react-error-boundary

import { ErrorBoundary, useErrorBoundary } from 'react-error-boundary'

// Fallback component
function ErrorFallback({ error, resetErrorBoundary }) {
    return (
        <div role="alert" className="error-fallback">
            <h2>Something went wrong</h2>
            <p>{error.message}</p>
            <button onClick={resetErrorBoundary}>Try Again</button>
        </div>
    )
}

// Usage with FallbackComponent
function App() {
    return (
        <ErrorBoundary
            FallbackComponent={ErrorFallback}
            onError={(error, info) => console.error(error, info)}
            onReset={() => console.log('Reset!')}
        >
            <UserProfile />
        </ErrorBoundary>
    )
}

// Inline fallback
function App2() {
    return (
        <ErrorBoundary
            fallback={<p>Something went wrong</p>}
        >
            <UserProfile />
        </ErrorBoundary>
    )
}

// useErrorBoundary hook — throw errors from event handlers
function BuggyButton() {
    const { showBoundary } = useErrorBoundary()

    async function handleClick() {
        try {
            await fetchData()
        } catch (error) {
            showBoundary(error)  // propagate to nearest error boundary
        }
    }

    return <button onClick={handleClick}>Fetch Data</button>
}
import ErrorBoundary from './ErrorBoundary'

// Wrap individual sections — granular error handling
function Dashboard() {
    return (
        <div className="dashboard">
            {/* Each section has its own error boundary */}
            <ErrorBoundary fallback={<p>Chart failed to load</p>}>
                <RevenueChart />
            </ErrorBoundary>

            <ErrorBoundary fallback={<p>User list unavailable</p>}>
                <UserList />
            </ErrorBoundary>

            <ErrorBoundary fallback={<p>Activity feed unavailable</p>}>
                <ActivityFeed />
            </ErrorBoundary>
        </div>
    )
}

// Component that throws — for testing
function BuggyComponent() {
    throw new Error('I crashed!')
    return <p>Never renders</p>
}

// Reset key — remount component when key changes
function App() {
    const [resetKey, setResetKey] = React.useState(0)

    return (
        <ErrorBoundary
            key={resetKey}  // changing key remounts the boundary
            FallbackComponent={({ resetErrorBoundary }) => (
                <div>
                    <p>Error occurred</p>
                    <button onClick={() => setResetKey(k => k + 1)}>
                        Reload Component
                    </button>
                </div>
            )}
        >
            <BuggyComponent />
        </ErrorBoundary>
    )
}

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.