에러 바운더리(ErrorBoundary)

에러 바운더리(ErrorBoundary)

화면에 오류가 나면 사용자는 보통 하얀 화면이나 스택 트레이스만 보게 돼요. Remix의 ErrorBoundary 컴포넌트는 이런 상황에 대비한 복구 지점이에요. 일반 React 에러 바운더리와 비슷하게 작동하지만, 몇 가지 더 할 수 있는 일이 있어요. 라우트 컴포넌트에 에러가 나면 그 자리에 에러 바운더리가 렌더링되고, 부모 라우트 안에 중첩돼서 그려져요. 게다가 그 라우트의 로더나 액션 함수에서 난 에러도 에러 바운더리가 처리하니까, 한 라우트의 모든 에러를 한곳에서 다룰 수 있어요.

출처: Remix 공식 문서 — ErrorBoundary

언제 에러 바운더리가 필요한가

가장 흔한 사용 사례는 몇 가지로 나뉘어요.

  • 의도적으로 4xx 응답을 던져 에러 UI를 띄우기 — 예를 들어 잘못된 사용자 입력은 400, 인증되지 않은 접근은 401, 데이터를 찾지 못하면 404를 던지죠.
  • React가 렌더링 중 런타임 에러를 만나서 의도치 않게 Error가 날 때.

이렇게 던져진 값을 가져오려면 useRouteError 훅을 써요. Response를 던졌다면 자동으로 status/statusText/data 필드를 가진 ErrorResponse 인스턴스로 풀려서, 컴포넌트에서 await response.json()을 직접 할 필요가 없어요. 던져진 Response와 던져진 Error를 구분하려면 isRouteErrorResponse 유틸리티를 쓰면 돼요.

예시

import {
  isRouteErrorResponse,
  useRouteError,
} from "@remix-run/react";

export function ErrorBoundary() {
  const error = useRouteError();

  if (isRouteErrorResponse(error)) {
    return (
      <div>
        <h1>
          {error.status} {error.statusText}
        </h1>
        <p>{error.data}</p>
      </div>
    );
  } else if (error instanceof Error) {
    return (
      <div>
        <h1>Error</h1>
        <p>{error.message}</p>
        <p>The stack trace is:</p>
        <pre>{error.stack}</pre>
      </div>
    );
  } else {
    return <h1>Unknown Error</h1>;
  }
}

먼저 useRouteError()로 오류 객체를 받아요. 그다음 isRouteErrorResponse로 던져진 Response인지 확인하고, 맞다면 상태 코드·상태 텍스트·데이터로 안내 UI를 그리고, 아니라면 일반 Error인지, 아예 모르는 값인지에 따라 다르게 처리해요. 이렇게 세 가지 경우를 나눠 다루면 사용자에게 더 친절한 화면을 보여줄 수 있어요.

더 알아보기