Skip to content

Commit c8ef5a0

Browse files
committed
feat: Add RouteErrorBoundary for improved error handling and integrate react-error-boundary package
1 parent fa9e778 commit c8ef5a0

File tree

3 files changed

+112
-0
lines changed

3 files changed

+112
-0
lines changed

client/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
"react-dnd": "^16.0.1",
8080
"react-dnd-html5-backend": "^16.0.1",
8181
"react-dom": "^18.2.0",
82+
"react-error-boundary": "^5.0.0",
8283
"react-flip-toolkit": "^7.1.0",
8384
"react-gtm-module": "^2.0.11",
8485
"react-hook-form": "^7.43.9",

client/src/routes/index.tsx

+98
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import ShareRoute from './ShareRoute';
1515
import ChatRoute from './ChatRoute';
1616
import Search from './Search';
1717
import Root from './Root';
18+
import { useRouteError } from 'react-router-dom';
1819

1920
const AuthLayout = () => (
2021
<AuthContextProvider>
@@ -23,14 +24,109 @@ const AuthLayout = () => (
2324
</AuthContextProvider>
2425
);
2526

27+
function RouteErrorBoundary() {
28+
const typedError = useRouteError() as {
29+
message?: string;
30+
stack?: string;
31+
status?: number;
32+
statusText?: string;
33+
data?: unknown;
34+
};
35+
36+
const errorDetails = {
37+
message: typedError.message ?? 'An unexpected error occurred',
38+
stack: typedError.stack,
39+
status: typedError.status,
40+
statusText: typedError.statusText,
41+
data: typedError.data,
42+
};
43+
44+
return (
45+
<div
46+
role="alert"
47+
className="flex min-h-screen flex-col items-center justify-center bg-surface-primary bg-gradient-to-br"
48+
>
49+
<div className="bg-surface-primary/60 mx-4 w-full max-w-4xl rounded-2xl border border-border-light p-8 shadow-2xl backdrop-blur-xl">
50+
<h2 className="mb-6 text-center text-3xl font-medium tracking-tight text-text-primary">
51+
Oops! Something went wrong
52+
</h2>
53+
54+
{/* Error Message */}
55+
<div className="mb-4 rounded-xl border border-red-500/20 bg-red-500/5 p-4 text-sm text-gray-600 dark:text-gray-200">
56+
<h3 className="mb-2 font-medium">Error Message:</h3>
57+
<pre className="whitespace-pre-wrap text-sm font-light leading-relaxed text-text-primary">
58+
{errorDetails.message}
59+
</pre>
60+
</div>
61+
62+
{/* Status Information */}
63+
{(typeof errorDetails.status === 'number' ||
64+
typeof errorDetails.statusText === 'string') && (
65+
<div className="mb-4 rounded-xl border border-yellow-500/20 bg-yellow-500/5 p-4 text-sm text-text-primary">
66+
<h3 className="mb-2 font-medium">Status:</h3>
67+
<p className="text-text-primary">
68+
{typeof errorDetails.status === 'number' && `${errorDetails.status} `}
69+
{typeof errorDetails.statusText === 'string' && errorDetails.statusText}
70+
</p>
71+
</div>
72+
)}
73+
74+
{/* Stack Trace - Collapsible */}
75+
{errorDetails.stack && (
76+
<details className="mb-4 rounded-xl border border-border-light p-4">
77+
<summary className="mb-2 cursor-pointer text-sm font-medium text-text-primary">
78+
Stack Trace
79+
</summary>
80+
<pre className="overflow-x-auto whitespace-pre-wrap text-xs font-light leading-relaxed text-text-primary">
81+
{errorDetails.stack}
82+
</pre>
83+
</details>
84+
)}
85+
86+
{/* Additional Error Data */}
87+
{errorDetails.data && (
88+
<details className="mb-4 rounded-xl border border-border-light p-4">
89+
<summary className="mb-2 cursor-pointer text-sm font-medium text-text-primary">
90+
Additional Details
91+
</summary>
92+
<pre className="whitespace-pre-wrap text-xs font-light leading-relaxed text-text-primary">
93+
{JSON.stringify(errorDetails.data, null, 2)}
94+
</pre>
95+
</details>
96+
)}
97+
98+
<div className="mt-6 flex flex-col gap-4">
99+
<p className="text-sm font-light text-text-secondary">Please try one of the following:</p>
100+
<ul className="list-inside list-disc text-sm text-text-secondary">
101+
<li>Refresh the page</li>
102+
<li>Clear your browser cache</li>
103+
<li>Check your internet connection</li>
104+
<li>Contact the Admin if the issue persists</li>
105+
</ul>
106+
<div className="mt-4 flex justify-center gap-4">
107+
<button
108+
onClick={() => window.location.reload()}
109+
className="rounded-lg bg-surface-submit px-4 py-2 text-white transition-colors hover:bg-surface-submit-hover"
110+
>
111+
Refresh Page
112+
</button>
113+
</div>
114+
</div>
115+
</div>
116+
</div>
117+
);
118+
}
119+
26120
export const router = createBrowserRouter([
27121
{
28122
path: 'share/:shareId',
29123
element: <ShareRoute />,
124+
errorElement: <RouteErrorBoundary />,
30125
},
31126
{
32127
path: '/',
33128
element: <StartupLayout />,
129+
errorElement: <RouteErrorBoundary />,
34130
children: [
35131
{
36132
path: 'register',
@@ -49,9 +145,11 @@ export const router = createBrowserRouter([
49145
{
50146
path: 'verify',
51147
element: <VerifyEmail />,
148+
errorElement: <RouteErrorBoundary />,
52149
},
53150
{
54151
element: <AuthLayout />,
152+
errorElement: <RouteErrorBoundary />,
55153
children: [
56154
{
57155
path: '/',

package-lock.json

+13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)