Skip to content

[#918] lazy/dynamic 위젯에 클라이언트 ErrorBoundary 도입 #1060

Description

@thxforall

Parent

#918 — 🗺️ [wayfinder] Error page 준수 (결정 D8)

What to build

코드베이스에 클라이언트 에러 바운더리가 하나도 없다react-error-boundary 미설치, 자체 componentDidCatch/getDerivedStateFromError 구현도 0건.

Next의 라우트 error.tsx는 서버 렌더와 데이터 fetch 에러를 잡지만 클라이언트 청크 로드 실패는 못 잡는다. 실제 위험은 배포 중이다: 새 배포가 나가면 구 청크 URL이 404가 되고, 그 시점에 열려 있던 세션이 dynamic() 위젯을 처음 열면 청크 로드가 실패한다. 현재 코드베이스에 dynamic() 6곳이 실사용 중이다(내비게이션·모달·온보딩 프롬프트 등) — 이 중 nav처럼 상시 마운트되는 것이 죽으면 화면 전체가 함께 죽는다.

lazy/dynamic 경계에 클라이언트 바운더리를 둬서, 위젯 하나가 실패해도 그 위젯만 대체 UI로 격리되고 나머지 페이지는 살아 있게 한다.

전역 래핑은 하지 않는다(D8). 라우트 error.tsx와 이중으로 잡으면 에러가 어디서 처리됐는지 알 수 없어 진단이 어려워진다. 적용 범위는 dynamic() 경계로 한정한다.

Acceptance criteria

  • react-error-boundary 의존성이 추가된다
  • dynamic()로 로드되는 위젯이 청크 로드에 실패해도 나머지 페이지가 계속 동작한다 — 실패를 인위적으로 주입해 재현 확인
  • 실패한 위젯 자리에 조용한 대체 UI가 뜬다 (전면 에러 화면이 아니라 위젯 크기의 격리된 처리)
  • 상시 마운트되는 위젯(내비게이션류)의 실패가 페이지 전체를 죽이지 않는다
  • 바운더리에 걸린 에러가 Sentry로 보고된다 — 라우트 error.tsx가 보고한 건과 구분 가능해야 한다(어느 경계가 잡았는지)
  • 전역/루트 래핑을 하지 않는다 — 적용 대상이 dynamic() 경계로 한정됨을 확인 (D8)
  • 대체 UI가 시맨틱 토큰만 쓴다 (하드코딩 hex 0)
  • 번들 크기 영향을 PR에 기록한다

Blocked by

None - can start immediately

Metadata

Metadata

Assignees

No one assigned

    Labels

    bump:patchBug fixes / internal refactorfrontend프론트엔드ready-for-agentFully specified, ready for an AFK agent

    Type

    No type

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions