Mahamudul Hasan Rubel
HomeAboutProjectsSkillsExperienceBlogCoursesPhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • About
  • Projects
  • Skills
  • Experience
  • Blog
  • Courses
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
Lesson 27 of the React Fundamentals: Build Modern UIs from Scratch course
ReactJune 25, 20263 min read

Managing Errors: Professional Error Handling in React

Learn professional error handling in React. Discover how to catch API failures, store error messages in state, and provide clear UI feedback to your users.

ReactAPIError HandlingHooksJavaScriptfrontend

Previously in this course, we covered handling loading states to keep users informed while waiting for data. Now, we’ll address the inevitable reality of web development: things go wrong. Whether it's a 404, a server outage, or a lost connection, your application needs to handle these failures gracefully rather than leaving the user staring at a blank screen.

Understanding Error Handling from First Principles

When you use the fetch API, it only rejects the promise if there is a network error (like the user being offline). If the server responds with a 404 Not Found or 500 Internal Server Error, fetch considers the request "successful."

To provide robust error handling, you must manually check the response.ok property. If it’s false, you throw an error yourself. By wrapping these operations in a try-catch block, you can intercept both network failures and your own custom errors, then store that information in your component's state to provide UI feedback.

Implementing Error Handling

Let’s update our MovieBrowser component. We need a new piece of state to hold the error message.

JSX
import { useState, useEffect } from CE9178">'react';

function MovieBrowser() {
  const [movies, setMovies] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(null); // New state for error

  useEffect(() => {
    async function fetchMovies() {
      setIsLoading(true);
      setError(null); // Reset error on new request

      try {
        const response = await fetch(CE9178">'https://api.example.com/movies');
        
        // Manually check for HTTP errors
        if (!response.ok) {
          throw new Error(CE9178">'Failed to fetch movies. Please try again later.');
        }

        const data = await response.json();
        setMovies(data);
      } catch (err) {
        // Catch network errors or our thrown error
        setError(err.message);
      } finally {
        setIsLoading(false);
      }
    }

    fetchMovies();
  }, []);

  if (error) return <div className="error-box">{error}</div>;
  if (isLoading) return <div>Loading...</div>;

  return (
    <ul>
      {movies.map(movie => <li key={movie.id}>{movie.title}</li>)}
    </ul>
  );
}

Key Components of the Pattern

  1. Resetting State: Always call setError(null) at the start of your effect. If a user retries a failed request, you don't want the old error message lingering on the screen.
  2. The finally Block: Use this to ensure setIsLoading(false) runs regardless of whether the request succeeded or failed. This prevents your app from being stuck in a permanent loading state.
  3. Conditional Rendering: By checking if (error) before rendering the data, you prioritize informing the user that something went wrong.

While we are focusing on the frontend here, remember that designing error responses clients can actually use on the backend is equally important for a stable ecosystem. If you're interested in more advanced patterns, the TypeScript Result Pattern is a fantastic way to handle errors without relying on exceptions at all.

Hands-on Exercise

Modify your current movie browser project:

  1. Add an error state variable.
  2. Update your fetch logic to include a try-catch block.
  3. If response.ok is false, throw a descriptive error message.
  4. In your JSX, add a conditional check: if error exists, render a paragraph with the error text in red.

Common Pitfalls

  • Forgetting to throw: Beginners often forget that fetch doesn't throw on 404/500 errors. Always check response.ok.
  • Ignoring the finally block: If you only set setIsLoading(false) inside the try block, your spinner will spin forever if the request crashes.
  • Over-sharing details: Don't show raw technical stack traces to your users. Keep the message helpful and human-readable, like "Something went wrong" rather than "Error 500: Internal Server Exception at line 42."

Recap

We've successfully moved from "happy path" coding to production-ready API interaction. By using try-catch and response.ok, we ensure that our app can recover from network issues. Storing these errors in state allows us to use conditional rendering to show the user exactly what they need to know, maintaining a professional and reliable user experience.

Up next: We will learn how to use cleanup functions in useEffect to prevent memory leaks and handle component unmounting.

Previous lessonHandling Loading StatesNext lesson Cleanup Functions in useEffect
Back to Blog

Similar Posts

ReactJune 25, 20263 min read

Debouncing Search Input: Optimize API Requests in React

Stop overwhelming your server with every keystroke. Learn how to implement debouncing in React to optimize API performance and create snappier UIs.

Read more
ReactReactJune 25, 20263 min read

Fetching Data from an API: A Practical React Guide

Part of the course

React Fundamentals: Build Modern UIs from Scratch

beginner · Lesson 27 of 49

  1. 1

    Introduction to Component-Based Architecture

    4 min
  2. 2

    Understanding the Virtual DOM

    4 min
  3. 3

    Setting Up with Vite

    3 min

Master the fetch API in React to retrieve external data. Learn to perform asynchronous requests and store JSON responses in your component state effectively.

Read more
ReactReactJune 25, 20264 min read

Mastering useEffect Dependencies: Control Your React Lifecycle

Learn to master the useEffect dependency array to control exactly when your side effects run. Avoid infinite loops and optimize your React components today.

Read more
4

Mastering JSX Syntax

4 min
  • 5

    Creating Static Components

    3 min
  • 6

    Styling Components

    3 min
  • 7

    Passing Data with Props

    3 min
  • 8

    Dynamic Movie Cards

    3 min
  • 9

    Component Composition

    3 min
  • 10

    Conditional Rendering

    3 min
  • 11

    Rendering Lists of Data

    4 min
  • 12

    The Key Prop Explained

    4 min
  • 13

    Introduction to React State

    4 min
  • 14

    Managing State with useState

    3 min
  • 15

    Building an Interactive Search Bar

    3 min
  • 16

    Handling Click Events

    4 min
  • 17

    Updating State Based on Previous State

    4 min
  • 18

    Filtering the Movie List

    3 min
  • 19

    Handling Form Submissions

    3 min
  • 20

    Controlled Components

    4 min
  • 21

    Event Bubbling and Propagation

    3 min
  • 22

    Building a Movie Filter Toggle

    3 min
  • 23

    Introduction to Side Effects

    4 min
  • 24

    useEffect Dependencies

    4 min
  • 25

    Fetching Data from an API

    3 min
  • 26

    Handling Loading States

    3 min
  • 27

    Managing Errors

    3 min
  • 28

    Cleanup Functions in useEffect

    3 min
  • 29

    Debouncing Search Input

    3 min
  • 30

    Refactoring for Clean Code

    3 min
  • 31

    Folder Structure Best Practices

    4 min
  • 32

    Extracting Custom Hooks

    3 min
  • 33

    Prop Drilling and Context API

    Coming soon
  • 34

    Polishing the UI

    Coming soon
  • 35

    Finalizing the Movie Browser

    Coming soon
  • 36

    Review of Component Lifecycle

    Coming soon
  • 37

    Review of State Management

    Coming soon
  • 38

    Building a Modal Component

    Coming soon
  • 39

    Introduction to PropTypes

    Coming soon
  • 40

    Performance Optimization Basics

    Coming soon
  • 41

    Handling Browser History

    Coming soon
  • 42

    Working with LocalStorage

    Coming soon
  • 43

    Building a Favorites List

    Coming soon
  • 44

    Handling Media in React

    Coming soon
  • 45

    Introduction to Testing

    Coming soon
  • 46

    Debugging React Apps

    Coming soon
  • 47

    Deployment Basics

    Coming soon
  • 48

    Using External Libraries

    Coming soon
  • 49

    Advanced

    Coming soon
  • View full course