Skip to content

4jades/error-boundary

Repository files navigation

@jjades/error-boundary

일반적인 에러 바운더리부터 API 에러 전용 처리까지, 모든 에러 처리 요구사항을 하나의 패키지로 해결할 수 있습니다.

특징

  • 🔧 라우터 독립적: 모든 라우터 라이브러리와 호환 (Next.js, React Router, Tanstack Router 등)
  • 🚀 완전한 에러 바운더리 솔루션: 일반 ErrorBoundary + API 특화 ErrorBoundary 모두 제공
  • ignoreError 기능: 특정 에러를 무시하고 상위로 전파 (문자열, 숫자, 함수 패턴 지원)
  • 🎯 HTTP 에러 처리: API 에러 전용 처리 및 사용자 정의 액션 지원
  • 🌐 다중 HTTP 클라이언트: ky와 axios 모두 지원
  • 🔄 유연한 액션: 최대 호환성을 위한 네이티브 브라우저 History API 사용
  • 📦 의존성 통합: react-error-boundary 기능을 BaseErrorBoundary로 재내보내기
  • 📱 SSR 안전: 클라이언트와 서버 환경 모두에서 동작
  • 🎨 커스터마이징 가능: 자체 컴포넌트 사용 또는 내장 기본값 사용

설치

npm install @jjades/error-boundary
# 또는
yarn add @jjades/error-boundary
# 또는
pnpm add @jjades/error-boundary

Peer Dependencies

npm install react react-dom @tanstack/react-query

# HTTP 클라이언트 중 하나 이상 설치 (ApiErrorBoundary 사용 시)
npm install ky          # ky 사용 시
npm install axios       # axios 사용 시

📦 참고: react-error-boundary는 더 이상 별도로 설치할 필요가 없습니다. 모든 기능이 BaseErrorBoundary로 재내보내집니다.

패키지 구조

이 라이브러리는 계층적 구조로 설계되어 다양한 사용 사례를 지원합니다:

BaseErrorBoundary (react-error-boundary 재내보내기)
    ↓
ErrorBoundary (일반 에러 바운더리 + ignoreError 기능)
    ↓  
ApiErrorBoundary (API 에러 특화 처리)

어떤 컴포넌트를 사용해야 할까요?

  • ErrorBoundary: 일반적인 JavaScript 에러 처리 + ignoreError 기능이 필요한 경우
  • ApiErrorBoundary: HTTP API 에러를 특별히 처리하고 싶은 경우 (상태 코드별 메시지, 액션 등)
  • BaseErrorBoundary: 기존 react-error-boundary 사용자가 마이그레이션 없이 사용하는 경우

빠른 시작

1. 일반 ErrorBoundary 사용법

import { ErrorBoundary } from '@jjades/error-boundary';

function MyApp() {
  return (
    <ErrorBoundary
      fallbackRender={({ error, resetErrorBoundary }) => (
        <div>
          <h2>오류가 발생했습니다</h2>
          <p>{error.message}</p>
          <button onClick={resetErrorBoundary}>다시 시도</button>
        </div>
      )}
    >
      <MyComponent />
    </ErrorBoundary>
  );
}

ignoreError 기능

특정 에러를 무시하고 상위로 전파시킬 수 있습니다:

import { ErrorBoundary } from '@jjades/error-boundary';

function MyApp() {
  return (
    <ErrorBoundary
      ignoreError={[
        'ChunkLoadError',           // 문자열 패턴으로 무시
        404,                        // 숫자 패턴으로 무시
        (error) => error.name === 'NetworkError'  // 함수로 조건부 무시
      ]}
      fallbackRender={({ error, resetErrorBoundary }) => (
        <div>에러: {error.message}</div>
      )}
    >
      <MyComponent />
    </ErrorBoundary>
  );
}

2. BaseErrorBoundary 사용법

기존 react-error-boundary와 동일한 API를 제공합니다:

import { BaseErrorBoundary } from '@jjades/error-boundary';

function MyApp() {
  return (
    <BaseErrorBoundary
      FallbackComponent={ErrorFallback}
      onError={(error, errorInfo) => console.log(error)}
    >
      <MyComponent />
    </BaseErrorBoundary>
  );
}

3. ApiErrorBoundary 사용법

API 에러 전용 처리:

import { ApiErrorBoundary } from '@jjades/error-boundary';

function MyPage() {
  return (
    <ApiErrorBoundary>
      <ComponentThatMakesAPIRequests />
    </ApiErrorBoundary>
  );
}

2. 라우터별 사용 예제

Next.js (App Router)

// app/layout.tsx
import { ApiErrorBoundary } from '@jjades/error-boundary';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <ApiErrorBoundary>
          {children}
        </ApiErrorBoundary>
      </body>
    </html>
  );
}

// 페이지 컴포넌트
import { ApiErrorBoundary } from '@jjades/error-boundary';

export default function Page() {
  return (
    <ApiErrorBoundary>
      <MyAPIComponent />
    </ApiErrorBoundary>
  );
}

커스터마이징

사용자 정의 버튼 컴포넌트

import { ApiErrorBoundary } from '@jjades/error-boundary';

const MyButton = ({ onClick, children, className }) => (
  <button 
    onClick={onClick} 
    className={`my-custom-button ${className}`}
  >
    {children}
  </button>
);

function MyPage() {
  return (
    <ApiErrorBoundary Button={MyButton}>
      <MyComponent />
    </ApiErrorBoundary>
  );
}

사용자 정의 에러 메시지

import { ApiErrorBoundary, type PartialErrorConfig } from '@jjades/error-boundary';

const customConfig: PartialErrorConfig = {
  404: {
    type: 'default',
    name: '페이지를 찾을 수 없음',
    message: '요청하신 페이지를 찾을 수 없습니다! 😅',
    action: {
      type: 'go-root',
      message: '홈으로 이동',
    },
  },
  401: {
    type: 'custom',
    fallback: <MyCustomLoginPrompt />,
  },
};

function MyPage() {
  return (
    <ApiErrorBoundary overrideConfig={customConfig}>
      <MyComponent />
    </ApiErrorBoundary>
  );
}

동적 에러 UI (fallback 함수)

import { ApiErrorBoundary } from '@jjades/error-boundary';

const customConfig = {
  500: {
    type: 'custom',
    fallback: (error, resetErrorBoundary) => (
      <div className="error-container">
        <h2>서버 오류가 발생했습니다</h2>
        <p>에러 코드: {error.response?.status}</p>
        <button onClick={resetErrorBoundary}>다시 시도</button>
      </div>
    ),
  },
};

function MyPage() {
  return (
    <ApiErrorBoundary overrideConfig={customConfig}>
      <MyComponent />
    </ApiErrorBoundary>
  );
}

사용자 정의 컨테이너

import { ApiErrorBoundary } from '@jjades/error-boundary';

const ErrorContainer = ({ children }) => (
  <div className="error-container">
    <header>내 앱 - 에러</header>
    {children}
  </div>
);

function MyPage() {
  return (
    <ApiErrorBoundary FallbackContainer={ErrorContainer}>
      <MyComponent />
    </ApiErrorBoundary>
  );
}

API 참조

ErrorBoundary

일반적인 에러 바운더리 컴포넌트입니다. react-error-boundary의 모든 기능 + ignoreError 기능을 제공합니다.

Prop 타입 기본값 설명
children ReactNode - 에러 바운더리로 감쌀 컴포넌트들
fallback ReactNode - 에러 발생 시 보여줄 정적 컴포넌트
FallbackComponent ComponentType<FallbackProps> - 에러 발생 시 사용할 컴포넌트
fallbackRender (props: FallbackProps) => ReactNode - 에러 발생 시 실행할 렌더 함수
onError (error: Error, errorInfo: ErrorInfo) => void - 에러 발생 시 실행할 콜백
onReset () => void - 에러 바운더리 리셋 시 실행할 콜백
resetKeys Array<string|number|boolean|null|undefined> - 에러 바운더리 리셋을 트리거하는 키들
resetOnPropsChange boolean false props 변경 시 자동 리셋 여부
ignoreError Array<string|number|((error: Error) => boolean)> [] 무시할 에러 패턴들

BaseErrorBoundary

react-error-boundaryErrorBoundary와 동일한 API를 제공합니다. 기존 react-error-boundary 사용자를 위한 호환성 레이어입니다.

import { BaseErrorBoundary } from '@jjades/error-boundary';
// react-error-boundary의 ErrorBoundary와 동일하게 사용 가능

ApiErrorBoundary

API 에러 전용 에러 바운더리 컴포넌트입니다.

Prop 타입 기본값 설명
children ReactNode - 에러 바운더리로 감쌀 컴포넌트들
FallbackContainer ComponentType div 에러 UI를 위한 컨테이너 컴포넌트
Button ComponentType 내장 버튼 사용자 정의 버튼 컴포넌트
overrideConfig PartialErrorConfig - 기본 에러 메시지/액션 덮어쓰기
resetKeys unknown[] [pathname] 에러 바운더리 리셋을 트리거하는 키들
ignoreError Array [] 무시할 에러 타입들

에러 액션

라이브러리에 포함된 내장 액션들:

  • go-back: window.history.back()을 사용해 이전 페이지로 이동
  • go-login: window.history.replaceState()를 사용해 /login으로 이동
  • go-root: window.history.replaceState()를 사용해 /로 이동
  • retry: 에러 바운더리를 리셋하여 실패한 작업 재시도

에러 무시 기능

특정 에러를 무시하고 상위로 전파시키려면:

import { ApiErrorBoundary } from '@jjades/error-boundary';

function MyPage() {
  return (
    <ApiErrorBoundary 
      ignoreError={[
        404,                    // 404 상태 코드 무시
        'Not Found',            // 상태 텍스트 무시
        (error) => error.response?.status === 403  // 조건부 무시
      ]}
    >
      <MyComponent />
    </ApiErrorBoundary>
  );
}

네이티브 History API를 사용하는 이유

이 라이브러리는 라우터별 네비게이션 메서드 대신 네이티브 브라우저 History API(window.history.pushStatewindow.history.replaceState)를 사용합니다. 이 접근 방식은:

  • ✅ 모든 라우터 라이브러리와 호환
  • ✅ Next.js와 완벽 통합 (공식 문서에 따름)
  • ✅ 설정이 불필요
  • ✅ 프레임워크 독립적 호환성 유지

Next.js 공식 문서에 따르면, 이러한 네이티브 메서드들은 Next.js 라우터와 완벽하게 통합됩니다.

개발

이 라이브러리는 빠른 린팅과 포맷팅을 위해 Biome을 사용합니다:

# 코드 린팅
npm run lint

# 린팅 문제 수정
npm run lint:fix

# 코드 포맷팅
npm run format

# 타입 체크
npm run type-check

# 빌드
npm run build

# 테스트
npm run test

# 테스트 (watch 모드)
npm run test:watch

# 테스트 커버리지
npm run test:coverage

TypeScript 지원

이 라이브러리는 TypeScript로 작성되었으며 완전한 타입 정의를 포함합니다. 모든 props와 설정이 적절히 타입이 지정되어 최고의 개발자 경험을 제공합니다.

기여하기

기여를 환영합니다! 자세한 내용은 기여 가이드를 참조해주세요.

라이선스

MIT © jjades-fe