Web & App/Frontend Study

React _ loader/라우터 로 에러 핸들링

jimmmy_jin 2025. 1. 9. 07:35

loader와 비슷한 형태로 에러도 핸들이 가능하다.

일단 아래와 같은 코드로 하위 child 에서 에러가 발견됐을때

에러페이지를 띄울 수 있도록 설정이 가능하다.

const router = createBrowserRouter([
  {
    path: "/",
    element: <RootPage />,
    errorElement: <ErrorPage />,
    children: [
      { index: true, element: <HomePage /> },
      {
        path: "events",
        element: <EventsRootLayout />,
        children: [
          {
            index: true,
            element: <EventsPage />,
            loader: eventLoader,
          },
          { path: ":eventId", element: <EventDetailPage /> },
          { path: "new", element: <NewEventPage /> },
          { path: ":eventId/edit", element: <EditEventPage /> },
        ],
      },
    ],
  },
]);

 

errorElement로 위와같이 컴포넌트 배치가 가능하고, Router 내의 에러를 캐치해서 아래와 같은 방법으로

각각 설정해줄 수 있다.

import PageContent from "../components/PageContent";
import { useRouteError } from "react-router-dom";

function ErrorPage() {
  const error = useRouteError();
  console.log(error);

  let title = "An error occured";
  let message = "We're sorry, but an unexpected error occured. Please try again later.";

  if (error.status === 500) {
    message = JSON.parse(error.data).message;
  }
  if (error.status === 404) {
    title = "Not Found";
    message = "Could not find the resource you were looking for.";
  }

  return (
    <PageContent title={title}>
      <p>{message}</p>
    </PageContent>
  );
}

export default ErrorPage;

 

주요 포인트는 useRouteError 이고 주의할 점은 JSON.parse와 같은 데이터 형식을 유심히 봐야할 거 같고

아래의 코드는 해당 에러를 유발하는 페이지의 코드이다.

import { useLoaderData } from "react-router-dom";

import EventsList from "../components/EventsList";

function EventsPage() {
  const events = useLoaderData();

  //   if (events.isError) {
  //     return <p>{events.message}</p>;
  //   }
  return (
    <>
      <EventsList events={events} />
    </>
  );
}

export default EventsPage;

export async function loader() {
  const response = await fetch("http://localhost:8080/events");

  if (!response.ok) {
    //return { isError: true, message: "Failed to fetch events" };
    throw new Response(JSON.stringify({ message: "Failed to fetch events" }), { status: 500 });
  } else {
    const resData = await response.json();
    return resData.events;
  }
}

 

위와 같이 loader를 이용해서 데이터를 패치하는 과정에서 throw new Error를 통해서 에러를 설정해 줄 수 있다.

더 코드를 짧게 바꿔줄 수 있는 Json() 함수가 있다.

아래와 같은 방식으로 사용할 수 있는데 너무 오래된 버전에서는 사용 불가능 하다고 하는데,

현재 7.x 버전에서도 json 함수를 가져올 수 없는 버그가 발생된다.

사용 방법은 아래와 같은 방식으로 사용하고, 에러 받는 곳에서 json parse를 안해도된다.

import { useLoaderData, json } from "react-router-dom";

import EventsList from "../components/EventsList";

function EventsPage() {
  const events = useLoaderData();

  //   if (events.isError) {
  //     return <p>{events.message}</p>;
  //   }
  return (
    <>
      <EventsList events={events} />
    </>
  );
}

export default EventsPage;

export async function loader() {
  const response = await fetch("http://localhost:8080/eventsss");

  if (!response.ok) {
    //return { isError: true, message: "Failed to fetch events" };
    throw json({ message: "Could not fetch events" }, { status: 500 });
  } else {
    return response;
  }
}

 

위의 내용을 가지고

검색을 좀 해보니까 json() 을 Response.json으로 사용하면 똑같은 방법으로 사용이 가능하다.

throw Response.json({ message: "Could not fetch events" }, { status: 500 });