Files
2nd/00_Raw/Error Handling.md
T

9.4 KiB

Error Handling

📌 Brief Summary

React 애플리케이션에서의 Error Handling은 자바스크립트 에러로 인해 전체 앱이 중단되거나 백지 화면이 나타나는 것을 방지하는 기술입니다 [1, 2]. 핵심 메커니즘인 에러 바운더리(Error Boundaries)를 통해 하위 컴포넌트 트리에서 발생한 렌더링 에러를 포착하고, 대신 대체 UI(Fallback UI)를 보여줍니다 [1]. 이벤트 핸들러나 비동기 작업에서 발생하는 에러는 에러 바운더리가 처리할 수 없으므로 전통적인 try/catch 블록과 결합하여 포괄적인 에러 관리를 수행합니다 [3-5].

📖 Core Content

  • 에러 바운더리(Error Boundaries)의 동작 원리: 에러 바운더리는 하위 컴포넌트의 렌더링, 생명주기 메서드, 생성자에서 발생하는 에러를 잡는 특별한 React 클래스 컴포넌트입니다 [1, 5]. static getDerivedStateFromError() 메서드를 사용하여 에러 발생 시 상태를 업데이트하여 Fallback UI를 렌더링하고, componentDidCatch() 메서드를 사용하여 에러 정보를 로깅합니다 [6]. 이를 통해 특정 UI 부분에 버그가 있더라도 나머지 애플리케이션은 안정적으로 유지됩니다 [7].
  • 에러 포착의 한계 (예외 사항): 에러 바운더리는 트리에서 자신의 아래에 있는 컴포넌트의 에러만 포착할 수 있으며, 자기 자신에서 발생한 에러는 포착하지 못합니다 [8]. 또한, 이벤트 핸들러, 비동기 코드(예: setTimeout 또는 Promise), 서버 사이드 렌더링(SSR) 중 발생하는 에러는 포착할 수 없습니다 [5, 6].
  • 이벤트 핸들러와 비동기 코드의 에러 처리: 이벤트 핸들러는 렌더링 중에 실행되지 않으므로, 여기서 에러가 발생해도 React는 여전히 화면에 무엇을 표시해야 할지 알고 있습니다 [4]. 따라서 이러한 경우에는 자바스크립트의 표준 명령형 코드 에러 처리 방식인 try/catch 문을 직접 사용해야 합니다 [3-5].
  • 포착되지 않은 에러(Uncaught Errors)의 결과: React 16부터는 에러 바운더리에 의해 포착되지 않은 에러가 발생할 경우, 손상된 UI를 그대로 두는 것이 보안이나 오작동(예: 잘못된 송금 금액 표시, 엉뚱한 사람에게 메시지 전송 등) 측면에서 더 위험하다고 판단하여 전체 React 컴포넌트 트리를 마운트 해제(Unmount)합니다 [9, 10].
  • 프로덕션 모니터링 및 디버깅: 에러 바운더리는 단순히 UI를 복구하는 것을 넘어, Sentry, LogRocket, SigNoz 등과 같은 프론트엔드 에러 로깅 서비스와 결합하여 프로덕션 환경의 에러를 기록하는 데 사용됩니다 [11]. 이 도구들은 지능형 에러 그룹화, 세션 리플레이, 전체 스택 트레이스를 제공하여 원인 파악을 돕습니다 [12-14].

⚖️ Trade-offs & Caveats

  • 클래스 컴포넌트 강제: 에러 바운더리는 오직 클래스 컴포넌트로만 만들 수 있습니다 [5, 8]. 현대의 React 코드베이스가 대부분 함수형 컴포넌트와 Hooks로 작성된다는 점을 고려하면 이질적인 구조가 될 수 있으며, 함수형으로 사용하려면 react-error-boundary와 같은 별도의 래퍼(Wrapper) 라이브러리에 의존해야 하는 제약이 있습니다 [5].
  • 전역 vs 지역 에러 바운더리의 딜레마: 앱 전체를 하나의 에러 바운더리로 감싸면 설정은 쉽지만, 작은 컴포넌트 하나의 오류로 인해 전체 UI가 Fallback으로 대체되어 사용자 경험이 저하될 수 있습니다 [11, 15]. 반대로 서드파티 위젯, 복잡한 폼 등 불안정한 요소를 개별적으로 감싸면(Granularity) 특정 영역만 에러 처리되어 나머지 앱을 사용할 수 있지만, 이를 설계하고 배치하는 작업의 복잡도와 관리 비용이 증가합니다 [9, 11, 15].
  • 완벽한 보호의 불가능: 앞서 언급된 것처럼 에러 바운더리는 비동기 로직이나 이벤트 핸들러의 에러를 잡지 못하므로, 애플리케이션의 성격상 데이터 페칭 등 비동기 로직이 많을 경우 에러 바운더리만으로는 시스템의 중단을 완전히 막을 수 없으며, 모든 상호작용 지점에 방어적인 로직(try/catch)을 추가해야 하는 수고가 따릅니다 [3, 4].

🔗 Knowledge Connections

[아키텍처/기반 기술]

  • Error Boundaries

    • 연결 이유: React 애플리케이션에서 선언형 UI 렌더링 중 발생하는 자바스크립트 에러를 처리하는 중심 메커니즘이기 때문입니다 [1].
    • 이 개념을 통해 더 깊게 이해할 수 있는 부분: 앱의 크래시를 방지하고 손상된 컴포넌트 대신 정상적인 대체 화면을 렌더링하는 React만의 에러 복구 전략을 파악할 수 있습니다 [1, 2, 10].
  • Component Lifecycle

    • 연결 이유: 에러 바운더리를 구현하기 위해서는 React 클래스 컴포넌트의 특정 생명주기 메서드(getDerivedStateFromError, componentDidCatch)가 필수적으로 요구되기 때문입니다 [6].
    • 이 개념을 통해 더 깊게 이해할 수 있는 부분: 렌더링 단계에서 어떻게 에러를 잡고 컴포넌트 상태를 업데이트하는지 내부 동작을 심층적으로 이해할 수 있습니다 [3, 6].

[구현/활용 도구]

  • Cloud Logging Tools

    • 연결 이유: 사용자 브라우저(프로덕션)에서 발생한 에러를 개발자가 인지하고 분석하기 위해서는 Sentry, LogRocket, Datadog 같은 외부 모니터링 툴 통합이 필수적이기 때문입니다 [11, 12, 14].
    • 이 개념을 통해 더 깊게 이해할 수 있는 부분: 발생한 에러의 스택 트레이스 추적, 사용자 세션 리플레이를 통한 상황 복원 등 심화된 에러 추적 기법을 배울 수 있습니다 [12-14].
  • try/catch

    • 연결 이유: 에러 바운더리로 처리할 수 없는 이벤트 핸들러, 비동기 통신 코드 내의 에러를 처리하는 표준 자바스크립트 방식이기 때문입니다 [3-5].
    • 이 개념을 통해 더 깊게 이해할 수 있는 부분: 선언형 에러 처리(Error Boundary)와 명령형 에러 처리(try/catch)의 역할 분담과 차이를 명확히 구분할 수 있습니다 [3, 4].

Deeper Research Questions

  • 이벤트 핸들러나 비동기 함수(예: setTimeout, Promise) 내부의 에러가 React의 렌더링 사이클에서 벗어나 에러 바운더리에 포착되지 않는 근본적인 아키텍처적 이유는 무엇인가?
  • 함수형 컴포넌트 시대에서 클래스 컴포넌트 기반의 에러 바운더리가 갖는 한계점은 무엇이며, 커뮤니티(예: react-error-boundary 등)는 이를 어떻게 극복하고 있는가?
  • 대규모 애플리케이션에서 페이지 레벨, 위젯 레벨 등 여러 겹으로 에러 바운더리를 중첩 배치(Nesting)할 때 에러가 상위로 전파(Propagate)되는 규칙과 효과적인 배치 전략은 무엇인가?
  • SSR(Server-Side Rendering) 환경을 지원하는 프레임워크(예: Next.js)에서는 클라이언트 중심의 React 에러 바운더리 외에 서버 측 에러를 어떻게 통합 관리하는가?
  • Sentry와 같은 외부 로깅 도구는 최소화(Minified)된 프로덕션 빌드 파일에서 에러가 났을 때, 어떻게 원래 컴포넌트와 발생 위치를 정확히 매핑하여 알려주는가?

Practical Application Contexts

  • Implementation: React 컴포넌트 작성 시 하얀 화면이 뜨는 것을 막기 위해 최상단이나 불안정한 서드파티 위젯 주위에 ErrorBoundary 클래스 컴포넌트를 작성하고 fallback UI 프로퍼티를 설정합니다 [2, 9, 15]. 비동기 호출 시에는 반드시 try/catch로 감싸 별도의 에러 처리를 구현합니다 [3, 5].
  • System Design: 페이스북 메신저의 예시처럼, 사이드바, 정보 패널, 메시지 입력창 등 독립적인 기능을 각각 에러 바운더리로 감싸 한 기능이 고장 나도 시스템의 다른 기능은 계속 상호작용 가능하도록 설계합니다 [15, 16].
  • Operation / Maintenance: 프로덕션에 배포된 애플리케이션에 Sentry 같은 관측성(Observability) 도구를 연결해 에러 바운더리의 componentDidCatch에서 에러를 전송하도록 구성하여 사용자 불만 접수 이전에 버그를 식별하고 디버깅합니다 [11, 14].
  • Learning Path: 자바스크립트의 기본적인 try/catch 명령형 에러 처리 방식을 먼저 숙지하고, 이후 React의 컴포넌트 생명주기와 에러 바운더리를 결합한 선언적 에러 처리 기법을 학습하며, 마지막으로 클라우드 로깅 툴 통합을 배웁니다.
  • My Project Relevance: 현재 진행 중인 프로젝트의 복잡성에 맞게 치명적인 오류로부터 앱 전체 크래시를 방지할 에러 바운더리의 배치 위치를 결정하고, 미처 파악하지 못한 프로덕션 에러의 모니터링 체계를 도입하는 데 직접적으로 적용할 수 있습니다.

Adjacent Topics

  • State Management
    • 확장 방향: Redux, Zustand 등의 전역 상태 관리 도구 내에서 발생하는 비동기 데이터 페칭 에러나 데이터 정규화(Normalization) 과정의 예외가 UI 에러 바운더리와 어떻게 상호 작용하며 처리되는지 확장하여 연구할 수 있습니다.

Last updated: 2026-04-30