← Back to list

error-boundaries
by oakoss
Open-source SaaS starter kit with React, TanStack, and Better Auth
⭐ 0🍴 0📅 Jan 26, 2026
SKILL.md
name: error-boundaries description: React error boundaries + fallback UIs. Use for error, catch, boundary, fallback, recovery, crash, ErrorBoundary, errorComponent, reset
Error Boundaries
Quick Start
TanStack Router provides built-in error handling:
import { Button } from '@oakoss/ui';
export const Route = createFileRoute('/posts/$id')({
errorComponent: ({ error, reset }) => (
<div className="p-4">
<h2>Something went wrong</h2>
<p>{error.message}</p>
<Button onPress={reset}>Try again</Button>
</div>
),
});
Error Component Types
| Level | Component | Use Case |
|---|---|---|
| Route | errorComponent | Route-specific errors |
| Global | defaultErrorComponent | Fallback for all routes |
| Not Found | notFoundComponent | 404 errors |
Route-Level Error Boundary
import { Button } from '@oakoss/ui';
import { AlertCircle } from 'lucide-react';
export const Route = createFileRoute('/dashboard')({
component: DashboardComponent,
errorComponent: DashboardError,
pendingComponent: DashboardLoading,
});
function DashboardError({ error, reset }: ErrorComponentProps) {
return (
<div className="flex flex-col items-center gap-4 p-8">
<AlertCircle className="size-12 text-destructive" />
<h2 className="text-lg font-semibold">Failed to load dashboard</h2>
<p className="text-muted-foreground">{error.message}</p>
<Button onPress={reset}>Retry</Button>
</div>
);
}
Global Error Boundary
Configure in router setup:
// apps/web/src/router.tsx
import { GlobalError } from '@/components/errors/global-error';
import { NotFoundError } from '@/components/errors/not-found-error';
export const getRouter = () =>
createRouter({
routeTree,
defaultErrorComponent: GlobalError,
defaultNotFoundComponent: NotFoundError,
});
Error Component Props
type ErrorComponentProps = {
error: Error; // The caught error
reset: () => void; // Retry the operation
info?: { componentStack: string }; // React error info
};
Fallback UI Patterns
Minimal Fallback
function MinimalError({ error, reset }: ErrorComponentProps) {
return (
<div className="p-4 text-center">
<p>Something went wrong.</p>
<Button variant="link" onPress={reset}>
Try again
</Button>
</div>
);
}
Detailed Fallback
import { Card, CardHeader, CardContent, CardFooter, Button } from '@oakoss/ui';
import { AlertTriangle } from 'lucide-react';
function DetailedError({ error, reset }: ErrorComponentProps) {
return (
<Card className="mx-auto max-w-md">
<CardHeader>
<h2 className="flex items-center gap-2 text-lg font-semibold">
<AlertTriangle className="text-destructive" />
Error
</h2>
</CardHeader>
<CardContent>
<p className="text-muted-foreground">{error.message}</p>
{process.env.NODE_ENV === 'development' && (
<pre className="mt-4 overflow-auto rounded bg-muted p-2 text-xs">
{error.stack}
</pre>
)}
</CardContent>
<CardFooter className="gap-2">
<Button onPress={reset}>Retry</Button>
<Button variant="secondary" onPress={() => window.location.reload()}>
Reload page
</Button>
</CardFooter>
</Card>
);
}
Not Found Component
import { notFound, Link } from '@tanstack/react-router';
import { Button } from '@oakoss/ui';
export const Route = createFileRoute('/posts/$id')({
loader: async ({ params }) => {
const post = await getPost(params.id);
if (!post) throw notFound();
return post;
},
notFoundComponent: () => (
<div className="p-8 text-center">
<h2 className="text-xl font-semibold">Post not found</h2>
<p className="text-muted-foreground">
The post you're looking for doesn't exist.
</p>
<Button className="mt-4" asChild>
<Link to="/posts">Back to posts</Link>
</Button>
</div>
),
});
Triggering Not Found
import { notFound } from '@tanstack/react-router';
// In loader
export const Route = createFileRoute('/posts/$id')({
loader: async ({ params }) => {
const post = await getPost(params.id);
if (!post) throw notFound();
return post;
},
});
// In component
function PostContent() {
const post = Route.useLoaderData();
if (!post.published) throw notFound();
return <article>...</article>;
}
Common Mistakes
| Mistake | Correct Pattern |
|---|---|
| Not providing reset function | Always include retry/reset button |
| Catching errors in component | Let errors bubble to boundary |
| Missing route error component | Add errorComponent to routes |
| Not logging errors | Log to console and/or external service |
| Showing stack trace in prod | Only show in NODE_ENV === 'development' |
| Generic error message | Show context-specific messages |
| Missing notFoundComponent | Handle 404s at route level |
| Swallowing async errors | Use error boundaries with Suspense |
| No reload/escape option | Provide "Reload page" fallback button |
| Not handling loader errors | Loader errors need errorComponent too |
Delegation
- Error logging: For monitoring, consider external services
- Code review: After creating error components, delegate to
code-revieweragent
Related Skills
- Server error handling: server-functions - Error codes, structured responses
- Route loaders: tanstack-router - Loader errors, notFound()
- Integration flows: integration-patterns - Full error handling patterns
Score
Total Score
65/100
Based on repository quality metrics
✓SKILL.md
SKILL.mdファイルが含まれている
+20
✓LICENSE
ライセンスが設定されている
+10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
✓最近の活動
1ヶ月以内に更新
+10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
✓タグ
1つ以上のタグが設定されている
+5
Reviews
💬
Reviews coming soon

