feat: added proper error messages on load
Signed-off-by: Varun Raj <mailme@varunraj.in>
This commit is contained in:
@@ -6,6 +6,8 @@ import { getMe } from "@/handlers/api/user.handler";
|
||||
import UserContext from "@/contexts/CurrentUserContext";
|
||||
import ErrorBlock from "../shared/ErrorBlock";
|
||||
import Loader from "../ui/loader";
|
||||
import { ArrowRight, TriangleAlert } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
|
||||
type RootLayoutProps = {
|
||||
children: ReactNode;
|
||||
@@ -14,13 +16,16 @@ type RootLayoutProps = {
|
||||
export default function RootLayout({ children }: RootLayoutProps) {
|
||||
const [user, setUser] = useState<IUser | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||
const [errorMessage, setErrorMessage] = useState<{
|
||||
error: string;
|
||||
message: string;
|
||||
} | null>(null);
|
||||
|
||||
const fetchData = () => {
|
||||
return getMe()
|
||||
.then(setUser)
|
||||
.catch((error) => {
|
||||
setErrorMessage(error.message);
|
||||
setErrorMessage(error);
|
||||
})
|
||||
.finally(() => setLoading(false));
|
||||
};
|
||||
@@ -29,12 +34,33 @@ export default function RootLayout({ children }: RootLayoutProps) {
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
if (loading) return <Loader />
|
||||
if (errorMessage) return <ErrorBlock description={errorMessage} />;
|
||||
if (loading) return <Loader />;
|
||||
if (errorMessage)
|
||||
return (
|
||||
<div className="min-h-screen flex flex-col justify-center">
|
||||
<ErrorBlock
|
||||
icon={<TriangleAlert />}
|
||||
title={errorMessage.error}
|
||||
description={errorMessage.message}
|
||||
action={
|
||||
<Link
|
||||
className="flex items-center gap-2 text-xs"
|
||||
href={
|
||||
"https://github.com/varun-raj/immich-power-tools?tab=readme-ov-file#-getting-started"
|
||||
}
|
||||
target="_blank"
|
||||
>
|
||||
Setup Instructions
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
</Link>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
if (!user) return null;
|
||||
|
||||
return (
|
||||
<UserContext.Provider value={user}>
|
||||
<UserContext.Provider value={user}>
|
||||
<div className="grid max-h-screen min-h-screen w-full md:grid-cols-[200px_1fr] lg:grid-cols-[240px_1fr]">
|
||||
<Sidebar />
|
||||
<div className="flex flex-col">{children}</div>
|
||||
|
||||
@@ -4,15 +4,17 @@ interface ErrorBlockProps {
|
||||
icon?: React.ReactNode;
|
||||
title?: string;
|
||||
description?: string;
|
||||
action?: React.ReactNode;
|
||||
}
|
||||
export default function ErrorBlock(
|
||||
{ icon, title, description }: ErrorBlockProps
|
||||
{ icon, title, description, action }: ErrorBlockProps
|
||||
) {
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center w-full h-full space-y-4 py-10">
|
||||
{icon}
|
||||
{title && <h2 className="text-xl font-semibold">{title}</h2>}
|
||||
{description && <p className="text-gray-500">{description}</p>}
|
||||
{action || null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { GalleryVerticalEnd, Home, Image, LocateOff, User } from "lucide-react";
|
||||
import { GalleryVerticalEnd, Home, Image, LocateOff, MapPinX, User } from "lucide-react";
|
||||
|
||||
export const sidebarNavs = [
|
||||
{
|
||||
@@ -19,6 +19,6 @@ export const sidebarNavs = [
|
||||
{
|
||||
title: "Missing Locations",
|
||||
link: "/assets/missing-locations",
|
||||
icon: <LocateOff className="h-4 w-4" />,
|
||||
icon: <MapPinX className="h-4 w-4" />,
|
||||
},
|
||||
];
|
||||
|
||||
+29
-1
@@ -3,6 +3,34 @@ import axios from 'axios'
|
||||
import qs from 'qs'
|
||||
|
||||
|
||||
const handleErrors = (error: AxiosError | any) => {
|
||||
if (error.code === "ERR_BAD_RESPONSE") {
|
||||
return Promise.reject({
|
||||
error: "Unable to process this request, please try again later",
|
||||
message: error.code
|
||||
});
|
||||
}
|
||||
let errorObject = {}
|
||||
if (error.response) {
|
||||
const { status } = error.response
|
||||
if (status === 422) {
|
||||
errorObject = {
|
||||
...error.response.data,
|
||||
message: 'Unable to process this request, please try again later',
|
||||
}
|
||||
} else {
|
||||
errorObject = {
|
||||
...error.response.data,
|
||||
}
|
||||
}
|
||||
return Promise.reject(errorObject)
|
||||
}
|
||||
errorObject = {
|
||||
message: 'Network Error. Please check your connection and try again!',
|
||||
}
|
||||
return Promise.reject(errorObject)
|
||||
}
|
||||
|
||||
export default class API {
|
||||
|
||||
|
||||
@@ -91,6 +119,6 @@ export default class API {
|
||||
options.headers = Object.assign(API.headers(contentType), headers)
|
||||
return axios(options)
|
||||
.then((responseJson) => responseJson.data)
|
||||
// .catch(handleErrors)
|
||||
.catch(handleErrors)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,6 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
res.end()
|
||||
} catch (error) {
|
||||
console.error('Proxy error:', error)
|
||||
res.status(500).json({ error: 'Internal Server Error' })
|
||||
res.status(500).json({ error })
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user