Skip to content

Commit 6cd8f2d

Browse files
committed
feat: modernize error boundary with design system
- Add proper error icon with animated glow effect - Show error code badge for route errors - Display contextual titles (404, server error, etc.) - Add collapsible technical details with stack trace - Include Try Again and Go Home action buttons - Apply card-based layout with gradient background - Add fade-in animation for smooth appearance
1 parent 3de2cf7 commit 6cd8f2d

1 file changed

Lines changed: 88 additions & 16 deletions

File tree

src/renderer/src/components/common/ErrorComponent.tsx

Lines changed: 88 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,102 @@
1-
/* eslint-disable @typescript-eslint/no-explicit-any */
21
import { Link, isRouteErrorResponse, useRouteError } from 'react-router-dom'
2+
import { AlertTriangle, Home, RefreshCw, FileWarning, ServerCrash } from 'lucide-react'
3+
import { Button } from '../ui/button'
4+
import { Card, CardContent } from '../ui/card'
5+
import { IconBox } from '../layouts/IconBox'
36

47
export default function ErrorPage() {
5-
const error = useRouteError() as any
8+
const error = useRouteError() as Error | Response | unknown
69
console.error(error)
710

8-
let errorMessage = ''
11+
// Determine error type and message
12+
let errorMessage = 'An unexpected error occurred'
13+
let errorTitle = 'Something went wrong'
14+
let errorCode: string | number | null = null
15+
let ErrorIcon = AlertTriangle
16+
917
if (isRouteErrorResponse(error)) {
10-
errorMessage = error.statusText
18+
errorCode = error.status
19+
errorMessage = error.statusText || error.data?.message || 'Route error'
20+
21+
if (error.status === 404) {
22+
errorTitle = 'Page not found'
23+
errorMessage = "The page you're looking for doesn't exist or has been moved."
24+
ErrorIcon = FileWarning
25+
} else if (error.status >= 500) {
26+
errorTitle = 'Server error'
27+
ErrorIcon = ServerCrash
28+
}
1129
} else if (error instanceof Error) {
1230
errorMessage = error.message
1331
}
1432

33+
const handleReload = () => {
34+
window.location.reload()
35+
}
36+
1537
return (
16-
<div className="text-center p-4 space-y-2 h-screen flex flex-col justify-center items-center rounded-lg">
17-
<h1 className="text-2xl font-bold">Oops!</h1>
18-
<p>Sorry, an unexpected error has occurred.</p>
19-
<p>
20-
<i>{errorMessage}</i>
21-
</p>
22-
23-
<div className="">
24-
Back to{' '}
25-
<Link to="/" className="hover:underline">
26-
Home
27-
</Link>
38+
<div className="min-h-screen flex items-center justify-center p-6 bg-background">
39+
<div className="w-full max-w-md animate-fade-in-up">
40+
{/* Error Icon */}
41+
<div className="flex justify-center mb-6">
42+
<div className="relative">
43+
<div className="absolute inset-0 bg-rose-500/20 rounded-full blur-xl animate-pulse-soft" />
44+
<IconBox icon={ErrorIcon} color="rose" size="xl" className="relative h-16 w-16" />
45+
</div>
46+
</div>
47+
48+
{/* Error Card */}
49+
<Card className="bg-gradient-to-br from-card to-card/80 border-rose-500/20">
50+
<CardContent className="p-6 text-center space-y-4">
51+
{/* Error Code Badge */}
52+
{errorCode && (
53+
<div className="inline-flex items-center px-3 py-1 rounded-full bg-rose-500/10 text-rose-500 text-xs font-medium">
54+
Error {errorCode}
55+
</div>
56+
)}
57+
58+
{/* Title */}
59+
<h1 className="text-2xl font-bold tracking-tight">{errorTitle}</h1>
60+
61+
{/* Message */}
62+
<p className="text-sm text-muted-foreground">{errorMessage}</p>
63+
64+
{/* Technical Details (collapsible for developers) */}
65+
{error instanceof Error && error.stack && (
66+
<details className="text-left mt-4">
67+
<summary className="text-xs text-muted-foreground cursor-pointer hover:text-foreground transition-colors">
68+
Technical details
69+
</summary>
70+
<pre className="mt-2 p-3 bg-muted/50 rounded-lg text-xs font-mono text-muted-foreground overflow-auto max-h-32">
71+
{error.stack}
72+
</pre>
73+
</details>
74+
)}
75+
76+
{/* Actions */}
77+
<div className="flex flex-col sm:flex-row gap-3 pt-4">
78+
<Button
79+
variant="outline"
80+
className="flex-1"
81+
onClick={handleReload}
82+
leftIcon={<RefreshCw className="h-4 w-4" />}
83+
>
84+
Try Again
85+
</Button>
86+
<Button variant="gradient" className="flex-1" asChild>
87+
<Link to="/">
88+
<Home className="h-4 w-4 mr-2" />
89+
Go Home
90+
</Link>
91+
</Button>
92+
</div>
93+
</CardContent>
94+
</Card>
95+
96+
{/* Help Text */}
97+
<p className="text-center text-xs text-muted-foreground mt-4">
98+
If this problem persists, please contact support.
99+
</p>
28100
</div>
29101
</div>
30102
)

0 commit comments

Comments
 (0)