REACT Error Handling

Handling errors in React is crucial for creating a smooth user experience. This guide covers error boundaries, try-catch, handling async errors, logging, and more.

1. Error Boundaries (Catching UI Errors)

React does not catch errors inside components by default. Error boundaries help prevent an entire application from crashing by catching errors in a specific part of the component tree.

Example: Creating an Error Boundary

import React from "react";

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    console.error("Error caught by boundary:", error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return <h2>Something went wrong. Please try again later.</h2>;
    }
    return this.props.children;
  }
}

export default ErrorBoundary;

Try It Now

Usage: Wrap Components in an Error Boundary

import ErrorBoundary from "./ErrorBoundary";
import MyComponent from "./MyComponent";

function App() {
  return (
    <ErrorBoundary>
      <MyComponent />
    </ErrorBoundary>
  );
}

export default App;

Try It Now

This prevents the entire application from crashing when an error occurs in a specific component.

2. Handling Errors in Event Handlers

Errors inside event handlers do not crash React, but they should still be handled properly.

Example: Try-Catch in Event Handlers

function MyComponent() {
  const handleClick = () => {
    try {
      throw new Error("Something went wrong!");
    } catch (error) {
      console.error("Caught error:", error);
      alert("An error occurred. Please try again.");
    }
  };

  return <button onClick={handleClick}>Click Me</button>;
}

Try It Now

Using try-catch prevents event-related errors from affecting the rest of the application.

 

3. Handling Errors in Async/Await Functions

Errors in asynchronous operations, such as API calls, need to be handled using try-catch.

Example: Try-Catch in API Calls

import { useState } from "react";

function FetchData() {
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);

  const fetchData = async () => {
    try {
      const response = await fetch("https://api.example.com/data");
      if (!response.ok) throw new Error("Failed to fetch data");
      const result = await response.json();
      setData(result);
    } catch (err) {
      setError(err.message);
    }
  };

  return (
    <div>
      <button onClick={fetchData}>Fetch Data</button>
      {error && <p style={{ color: "red" }}>Error: {error}</p>}
      {data && <pre>{JSON.stringify(data, null, 2)}</pre>}
    </div>
  );
}

Try It Now

This approach ensures that API failures do not crash the application.

4. Global Error Handling with window.onerror

For handling uncaught JavaScript errors globally, window.onerror or window.addEventListener("error") can be used.

Example: Global Error Logging

window.onerror = function (message, source, lineno, colno, error) {
  console.error("Global Error:", message, source, lineno, colno, error);
};

Try It Now

This helps in debugging and logging uncaught errors in the application.

 

5. Logging and Reporting Errors

For production applications, error logging services help in tracking and diagnosing issues. Popular services include:

  • Sentry – Real-time error tracking
  • LogRocket – Session recording and logging
  • Firebase Crashlytics – Frontend and backend error logging

Example: Logging Errors with Sentry

npm install @sentry/react

Try It Now

import * as Sentry from "@sentry/react";

Sentry.init({ dsn: "YOUR_SENTRY_DSN" });

function MyComponent() {
  const handleError = () => {
    try {
      throw new Error("Test error");
    } catch (error) {
      Sentry.captureException(error);
    }
  };

  return <button onClick={handleError}>Trigger Error</button>;
}

Try It Now

This approach helps track errors in production applications.

 

6. Handling Errors in React Router (404 Pages)

If a user navigates to an invalid route, displaying a custom 404 page improves the user experience.

Example: React Router 404 Page

import { BrowserRouter as Router, Routes, Route } from "react-router-dom";

function NotFound() {
  return <h2>404 - Page Not Found</h2>;
}

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="*" element={<NotFound />} />
      </Routes>
    </Router>
  );
}

Try It Now

This ensures that users are informed when they access an invalid URL.

 

7. Handling Errors in Next.js

Next.js provides built-in error handling using custom error pages.

Example: Custom 500 Error Page in Next.js

  1. Create a _error.js file inside pages/
    function Error({ statusCode }) {
      return (
        <p>
          {statusCode
            ? `An error ${statusCode} occurred on the server`
            : "An error occurred on the client"}
        </p>
      );
    }
    
    Error.getInitialProps = ({ res, err }) => {
      const statusCode = res ? res.statusCode : err ? err.statusCode : 404;
      return { statusCode };
    };
    
    export default Error;
    

    Try It Now

    This handles both client-side and server-side errors in Next.js applications.

     

Summary – React Error Handling Best Practices

  • Use Error Boundaries to catch UI errors and prevent crashes
  • Use try-catch in event handlers and async functions
  • Implement global error logging using window.onerror
  • Use Sentry or LogRocket for logging errors in production
  • Create custom 404 pages for handling invalid routes
  • Handle Next.js errors using _error.js