diff --git a/app/root.tsx b/app/root.tsx index 4c430d6..ae5daa3 100644 --- a/app/root.tsx +++ b/app/root.tsx @@ -16,6 +16,7 @@ import { ClerkProvider } from "@clerk/react-router"; import { dark } from "@clerk/themes"; import { Toaster } from "~/components/ui/sonner"; import { isUserAdminByClerkId } from "~/models/user"; +import { AlertCircle, FileQuestion, Lock, ShieldOff, ServerCrash } from "lucide-react"; export const middleware: Route.MiddlewareFunction[] = [clerkMiddleware()]; @@ -83,30 +84,95 @@ export default function App({ loaderData }: Route.ComponentProps) { } export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) { - let message = "Oops!"; - let details = "An unexpected error occurred."; + let status = 500; + let title = "Something Went Wrong"; + let message = "An unexpected error occurred. Please try again later."; let stack: string | undefined; - + let showSignInHint = false; if (isRouteErrorResponse(error)) { - message = error.status === 404 ? "404" : "Error"; - details = - error.status === 404 - ? "The requested page could not be found." - : error.statusText || details; - } else if (import.meta.env.DEV && error && error instanceof Error) { - details = error.message; - stack = error.stack; + status = error.status; + switch (error.status) { + case 401: + title = "Sign In Required"; + message = "You need to be signed in to access this page."; + showSignInHint = true; + break; + case 403: + title = "Access Denied"; + message = "You don't have permission to view this page."; + break; + case 404: + title = "Page Not Found"; + message = "The page you're looking for doesn't exist or has been moved."; + break; + default: + title = `Error ${error.status}`; + message = + typeof error.data === "string" && error.data + ? error.data + : error.statusText || "Something went wrong."; + } + } else if (error instanceof Error) { + title = "Unexpected Error"; + message = import.meta.env.DEV ? error.message : "An unexpected error occurred. Please try again later."; + stack = import.meta.env.DEV ? error.stack : undefined; } return ( -
-

{message}

-

{details}

- {stack && ( -
-          {stack}
-        
- )} -
+
+
+
+ + Brackt + +
+
+ +
+
+
+ {status} +
+ +
+ {statusIcon(status)} +
+ +
+

{title}

+

{message}

+
+ +
+ + {showSignInHint ? "Go to Home Page to Sign In" : "Go Home"} + +
+ + {stack && ( +
+ + Stack trace (development only) + +
+                {stack}
+              
+
+ )} +
+
+
); } + +function statusIcon(status: number) { + const cls = "h-14 w-14 text-muted-foreground"; + if (status === 401) return ; + if (status === 403) return ; + if (status === 404) return ; + if (status >= 500) return ; + return ; +}