Skip to content

[#918] (shell) 에러 경계 — 500·엔티티 404가 AppShell을 유지 #1056

Description

@thxforall

Parent

#918 — 🗺️ [wayfinder] Error page 준수 (결정 D1·D2·D3·D7 / 리스크 R1·R2)

What to build

현재 (shell) 트리에는 세그먼트 에러 경계가 하나도 없다. 그래서 shell 페이지가 throw하거나 notFound()를 부르면 루트 경계까지 튀어 AppShell 전체가 언마운트되고, 동시에 ConditionalNav가 shell 경로에서 자기억제하기 때문에 사이드바도 모바일 바도 없는 헐벗은 중앙 블록이 남는다. 사용자에게 남는 탈출구는 본문 안의 링크 하나뿐이다.

(shell) 세그먼트에 에러 경계와 not-found 경계를 두어, 500과 "엔티티 없음" 404가 AppShell 안에서 렌더되게 한다. 사이드바·모바일 상/하단 바가 살아 있어 사용자가 곧바로 다른 데로 이동할 수 있어야 한다.

두 경계 모두 본문은 shared/ErrorState·EmptyState 조합으로 만든다(#1055에서 보강한 것). hand-roll 금지 — 이 둘이 첫 소비자가 된다.

스코프 경계 (결정 D2에서 확정): 이번에 잡는 404는 페이지가 명시적으로 notFound()를 호출한 경우뿐이다. Next는 매칭되는 라우트 자체가 없는 URL(/ko/asdf)의 404를 nested not-found로 보내지 않고 무조건 루트로 보낸다. 이를 셸 안으로 끌어오려면 [...rest] catch-all shim이 필요한데, 향후 신규 라우트를 조용히 삼킬 위험이 있고 locale prefix 없는 /asdf는 그걸로도 못 잡아 어차피 통일이 안 된다 → 채택하지 않는다. 오타 URL은 루트 브랜드 404에 그대로 착지한다.

not-found 문구는 (shell) 공용 1개로 시작한다(D3). posts·items·artists·brands·profile의 notFound()를 전부 받으므로 일반형 문구 + 탐색 유도 CTA. 엔티티별 카피가 필요해지면 나중에 해당 라우트가 자기 not-found로 오버라이드하면 된다.

decoded/[id]는 실재하지 않는다(index 페이지뿐) — #921 본문의 오기이므로 대상에서 뺀다. cody/looks/[slug](shell) 밖이라 이번 스코프가 아니다(D5).

Acceptance criteria

  • shell 페이지가 throw했을 때 AppShell(데스크톱 사이드바 + 모바일 상/하단 바)이 유지된 채 에러가 렌더된다 — 실제로 throw를 발생시켜 재현 확인
  • shell 페이지가 notFound()를 호출했을 때(/ko/posts/<없는id>) 마찬가지로 AppShell이 유지된다
  • 500 화면에서 Next의 reset() 재시도와 홈 이동을 둘 다 할 수 있다
  • 404 화면에서 탐색으로 이동할 수 있다
  • 두 경계 모두 shared/ErrorState/EmptyState를 조합해 만든다 (hand-roll 금지, 하드코딩 hex 0)
  • 라이트/다크 양쪽에서 렌더 확인
  • 500 경계가 Sentry로 에러를 보고한다 (기존 루트 error.tsx와 동등한 수준)
  • 문구가 i18n 메시지로 들어간다 (ko/en)
  • R1 검증: @modal parallel route와의 상호작용을 실제로 확인한다. 루트 not-found.tsx 주석에 "@modal + auto not-found → React.Children.only" 회귀 이력이 남아 있고 @modal 슬롯이 app/@modal·app/[locale]/@modal 양쪽에 존재한다. dev·프로덕션 빌드 양쪽에서 shell throw와 notFound()를 재현해 이 에러가 나지 않음을 확인 — 재발하면 슬롯 default.tsx 보강으로 해소하고, 무엇이 필요했는지 이슈에 기록한다
  • R2 검증: bun run build(shell) 세그먼트가 dynamic으로 떨어지지 않았는지 확인한다 (#942의 setRequestLocale 정적 렌더 규율 회귀 금지)
  • 오타 URL(/ko/asdf)은 여전히 루트 404로 간다 — D2가 의도한 동작이며 회귀가 아님을 확인

Blocked by

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