🚸 Polish route error experience with shared alert layout#57
Conversation
WalkthroughAdds a new reusable RouteErrorView component and replaces/introduces route-level ErrorBoundary handlers in three routes to render standardized error UIs (mapping 400/403/404/other errors to tones, icons, and actions). No loader or core business logic changed; edits are limited to error rendering and imports. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Router as React Router
participant Route as Route Module
participant EB as ErrorBoundary
participant REV as RouteErrorView
User->>Router: navigate to route
Router->>Route: run loader/action
alt loader/action throws or returns error
Router->>EB: invoke ErrorBoundary
EB->>EB: useRouteError() / isRouteErrorResponse()
alt 404
EB->>REV: render (tone=neutral, icon=FileWarning, actions=[Library, Playlists])
else 400/403
EB->>REV: render (tone=warning, icon=ShieldAlert/Lock, actions=[Refresh/Library])
else other
EB->>REV: render (tone=critical, icon=AlertTriangle, actions=[Home/Retry])
end
REV-->>User: standardized error UI
else no error
Route-->>User: normal route UI
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
app/components/RouteErrorView.tsx(1 hunks)app/routes/player.$id.tsx(2 hunks)app/routes/playlists.$id.tsx(2 hunks)app/routes/playlists._index.tsx(2 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: TypeScript에서 any를 사용하지 않고 모든 함수에 포괄적인 타입 힌트를 제공한다 (strict TS)
로그에 비밀값을 남기지 않도록 모든 콘솔 출력은 민감정보를 마스킹/제거한다
**/*.{ts,tsx}: Use the ~/* path alias (from tsconfig.json) for internal imports
Prefer explicit interfaces when defining object shapes in TypeScript (strict mode)
Avoid using any in TypeScript (project runs in strict mode)
Use two-space indentation throughout TypeScript/TSX files
Name components, hooks, and providers with PascalCase
Name helpers and state setters with camelCase
File names should mirror their primary export
Files:
app/routes/playlists._index.tsxapp/routes/player.$id.tsxapp/components/RouteErrorView.tsxapp/routes/playlists.$id.tsx
**/*.{ts,tsx,md,mdx}
📄 CodeRabbit inference engine (CLAUDE.md)
코드 주석과 문서는 영어로 작성한다
Files:
app/routes/playlists._index.tsxapp/routes/player.$id.tsxapp/components/RouteErrorView.tsxapp/routes/playlists.$id.tsx
app/**
📄 CodeRabbit inference engine (AGENTS.md)
Place all React Router app source under app/ following the repository’s feature-sliced layout
Files:
app/routes/playlists._index.tsxapp/routes/player.$id.tsxapp/components/RouteErrorView.tsxapp/routes/playlists.$id.tsx
**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
Split multiline JSX props across lines per Stylistic ESLint rules
Files:
app/routes/playlists._index.tsxapp/routes/player.$id.tsxapp/components/RouteErrorView.tsxapp/routes/playlists.$id.tsx
app/components/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
app/components/**/*.tsx: React 컴포넌트에서는 비즈니스 로직을 금지하고 커스텀 훅과 프리젠테이션만 담당한다 (직접 API 호출 금지)
UI 텍스트는 영어를 사용한다 (향후 로컬라이즈 가능)
Files:
app/components/RouteErrorView.tsx
app/components/**
📄 CodeRabbit inference engine (AGENTS.md)
Place reusable UI primitives in app/components/
Files:
app/components/RouteErrorView.tsx
🧬 Code graph analysis (4)
app/routes/playlists._index.tsx (3)
app/routes/player.$id.tsx (1)
ErrorBoundary(93-143)app/routes/playlists.$id.tsx (1)
ErrorBoundary(84-139)app/components/RouteErrorView.tsx (1)
RouteErrorView(56-140)
app/routes/player.$id.tsx (2)
app/routes/playlists.$id.tsx (1)
ErrorBoundary(84-139)app/components/RouteErrorView.tsx (1)
RouteErrorView(56-140)
app/components/RouteErrorView.tsx (2)
app/lib/utils.ts (1)
cn(4-6)app/components/AppLayout.tsx (1)
AppLayout(30-42)
app/routes/playlists.$id.tsx (1)
app/components/RouteErrorView.tsx (1)
RouteErrorView(56-140)
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
app/routes/playlists._index.tsx (2)
64-64: Add explicit return type annotation for strict TS.As per coding guidelines, all functions should have comprehensive type hints in strict mode. Add an explicit return type annotation for clarity and type safety.
As per coding guidelines.
Apply this diff:
-export function ErrorBoundary() { +export function ErrorBoundary(): React.ReactElement {
71-71: Consider using a conventional error state icon for consistency.
RefreshCwtypically represents an action (refresh/retry) rather than an error state. Other routes in this PR use state indicators likeAlertTriangle,Lock, orFileWarning. For visual consistency, consider usingAlertCircleorAlertTrianglehere instead.Example:
- icon={<RefreshCw className="h-6 w-6" aria-hidden />} + icon={<AlertCircle className="h-6 w-6" aria-hidden />}Don't forget to import
AlertCircleif you make this change.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
app/routes/playlists._index.tsx(2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: TypeScript에서 any를 사용하지 않고 모든 함수에 포괄적인 타입 힌트를 제공한다 (strict TS)
로그에 비밀값을 남기지 않도록 모든 콘솔 출력은 민감정보를 마스킹/제거한다
**/*.{ts,tsx}: Use the ~/* path alias (from tsconfig.json) for internal imports
Prefer explicit interfaces when defining object shapes in TypeScript (strict mode)
Avoid using any in TypeScript (project runs in strict mode)
Use two-space indentation throughout TypeScript/TSX files
Name components, hooks, and providers with PascalCase
Name helpers and state setters with camelCase
File names should mirror their primary export
Files:
app/routes/playlists._index.tsx
**/*.{ts,tsx,md,mdx}
📄 CodeRabbit inference engine (CLAUDE.md)
코드 주석과 문서는 영어로 작성한다
Files:
app/routes/playlists._index.tsx
app/**
📄 CodeRabbit inference engine (AGENTS.md)
Place all React Router app source under app/ following the repository’s feature-sliced layout
Files:
app/routes/playlists._index.tsx
**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
Split multiline JSX props across lines per Stylistic ESLint rules
Files:
app/routes/playlists._index.tsx
🧬 Code graph analysis (1)
app/routes/playlists._index.tsx (2)
app/routes/playlists.$id.tsx (1)
ErrorBoundary(84-139)app/components/RouteErrorView.tsx (1)
RouteErrorView(56-140)
🔇 Additional comments (3)
app/routes/playlists._index.tsx (3)
2-5: LGTM!The imports follow best practices: per-icon imports from lucide-react for tree-shaking, proper React Router error handling utilities, and the path alias for internal imports.
73-77: LGTM! The error.data guard is correctly implemented.The
typeof error.data === 'string'guard properly addresses the previous review concern about non-string data breaking the React child rendering. The fallback to a generic message when data is not a string is a safe approach.
91-95: LGTM! Proper error instance checking.The
error instanceof Errorcheck correctly handles both Error instances and other thrown values, with an appropriate fallback message. This follows the same pattern as other routes in the codebase.
Summary
Testing
Summary by CodeRabbit
New Features
Refactor