Error page using Extended Error that contains category, reason, and error code.

This commit is contained in:
mbaharip
2023-05-25 20:32:10 +07:00
parent 11f866400f
commit 9734f800a1
2 changed files with 206 additions and 83 deletions
+121
View File
@@ -0,0 +1,121 @@
"use client";
// Error components must be Client Components
import { useEffect, useState } from "react";
import CompPassword from "components/compPassword";
import ExtendedError from "utils/generalHelper/extendedError";
import { Constant } from "types/general/constant";
export default function Error({
error,
reset,
}: {
error: Error;
reset: () => void;
}) {
const [extendedError, setExtendedError] =
useState<ExtendedError>();
const [path, setPath] = useState<string>("root");
useEffect(() => {
if (error.message.includes("{")) {
const errorObj = JSON.parse(
error.message,
) as ExtendedError;
const extendError = new ExtendedError(
errorObj.extendedMessage ||
Constant.apiInternalError,
errorObj.code || 500,
errorObj.category || "internalServerError",
errorObj.reason || "Internal Server Error",
);
setExtendedError(extendError);
const path =
extendError.reason?.split('"')[1].split('"')[0] ||
"root";
setPath(path);
} else {
const extendedError = new ExtendedError(
Constant.apiInternalError,
500,
"internalServerError",
error.message,
);
setExtendedError(extendedError);
}
}, [error]);
return (
<div
className={
"relative flex h-full min-h-[80dvh] w-full flex-grow flex-col items-center justify-center gap-8"
}
>
{/* Image placeholder */}
<div
className={
"grid h-48 w-48 place-items-center rounded-lg bg-blue-300 font-semibold text-zinc-900"
}
>
Placeholder Image
</div>
{extendedError?.code === 401 ? (
<>
<CompPassword path={path} />
</>
) : (
<>
{/* Error message */}
<div
className={
"flex max-w-screen-lg flex-col items-center gap-2"
}
>
<h1 className={"font-semibold"}>
{extendedError?.code}
</h1>
<p className={"font-medium"}>
{extendedError?.message}
</p>
<span>{path}</span>
<div
className={
"flex flex-row gap-2 tablet:flex-row"
}
>
<a href={"/"}>
<button className={"link"}>
Go back to home
</button>
</a>
<button
onClick={() => {
document.cookie = `next-gdrive-password={"Protected%20Folder%20-%20pass%20loremipsum":"5245a52778d684fa698f69861fb2e058b308f6a74fed5bf2fe77d97bad5e071c"}`;
reset();
}}
className={"interactive"}
>
Try again
</button>
</div>
</div>
{/* Error reason */}
<pre
className={
"absolute bottom-2 my-4 max-w-sm whitespace-pre-wrap rounded-lg border border-zinc-500/25 bg-zinc-100 px-4 py-2 text-xs dark:bg-zinc-900 md:max-w-screen-lg"
}
>
<b>{extendedError?.category}: </b>
{extendedError?.reason}
</pre>
</>
)}
</div>
);
}
+85 -83
View File
@@ -1,10 +1,13 @@
"use client"; // Error components must be Client Components
"use client";
// Error components must be Client Components
import { useEffect, useState } from "react";
import Image from "next/image";
import CompPassword from "components/compPassword";
import ExtendedError from "utils/generalHelper/extendedError";
import { Constant } from "types/general/constant";
import Link from "next/link";
export default function Error({
error,
@@ -13,50 +16,38 @@ export default function Error({
error: Error;
reset: () => void;
}) {
const [errorCode, setErrorCode] = useState<string>("");
const [errorMessage, setErrorMessage] =
useState<string>("");
const payload = new ExtendedError(
Constant.apiInternalError,
500,
"internalServerError",
error.message,
);
const extendedError =
error.message.split("Error: ")[1] === undefined
? JSON.parse(JSON.stringify(payload))
: JSON.parse(error.message.split("Error: ")[1]);
const [extendedError, setExtendedError] =
useState<ExtendedError>();
const [path, setPath] = useState<string>("root");
useEffect(() => {
const code = extendedError.code;
setErrorMessage(extendedError.extendedMessage);
switch (code) {
case 400:
setErrorCode("Error 400");
break;
case 401:
setErrorCode("Error 401");
break;
case 403:
setErrorCode("Error 403");
break;
case 404:
setErrorCode("Error 404");
break;
default:
setErrorCode("Error 500");
break;
if (error.message.includes("{")) {
const errorObj = JSON.parse(
error.message,
) as ExtendedError;
const extendError = new ExtendedError(
errorObj.extendedMessage ||
Constant.apiInternalError,
errorObj.code || 500,
errorObj.category || "internalServerError",
errorObj.reason || "Internal Server Error",
);
setExtendedError(extendError);
const path =
extendError.reason?.split('"')[1].split('"')[0] ||
"root";
setPath(path);
} else {
const extendedError = new ExtendedError(
Constant.apiInternalError,
500,
"internalServerError",
error.message,
);
setExtendedError(extendedError);
}
console.group(
`Error ${code}: ${extendedError.category}`,
);
console.error(
"Error message: ",
extendedError.extendedMessage,
);
console.table(extendedError);
console.groupEnd();
}, [extendedError]);
}, [error]);
return (
<div
@@ -73,47 +64,58 @@ export default function Error({
Placeholder Image
</div>
{/* Error message */}
<div
className={
"flex max-w-screen-lg flex-col items-center gap-2"
}
>
<h1 className={"font-semibold"}>
{extendedError.code}
</h1>
<p className={"font-medium"}>
{extendedError.extendedMessage}
</p>
<div
className={"flex flex-row gap-2 tablet:flex-row"}
>
<a href={"/"}>
<button className={"link"}>
Go back to home
</button>
</a>
<button
onClick={() => {
document.cookie = `next-gdrive-password={"Protected%20Folder%20-%20pass%20loremipsum":"5245a52778d684fa698f69861fb2e058b308f6a74fed5bf2fe77d97bad5e071c"}`;
reset();
}}
className={"interactive"}
{extendedError?.code === 401 ? (
<>
<CompPassword path={path} />
</>
) : (
<>
{/* Error message */}
<div
className={
"flex max-w-screen-lg flex-col items-center gap-2"
}
>
Try again
</button>
</div>
</div>
<h1 className={"font-semibold"}>
{extendedError?.code}
</h1>
<p className={"font-medium"}>
{extendedError?.message}
</p>
<span>{path}</span>
<div
className={
"flex flex-row gap-2 tablet:flex-row"
}
>
<a href={"/"}>
<button className={"link"}>
Go back to home
</button>
</a>
<button
onClick={() => {
document.cookie = `next-gdrive-password={"Protected%20Folder%20-%20pass%20loremipsum":"5245a52778d684fa698f69861fb2e058b308f6a74fed5bf2fe77d97bad5e071c"}`;
reset();
}}
className={"interactive"}
>
Try again
</button>
</div>
</div>
{/* Error reason */}
<pre
className={
"absolute bottom-2 my-4 max-w-sm whitespace-pre-wrap rounded-lg border border-zinc-500/25 bg-zinc-100 px-4 py-2 text-xs dark:bg-zinc-900 md:max-w-screen-lg"
}
>
<b>{extendedError.category}: </b>
{extendedError.reason}
</pre>
{/* Error reason */}
<pre
className={
"absolute bottom-2 my-4 max-w-sm whitespace-pre-wrap rounded-lg border border-zinc-500/25 bg-zinc-100 px-4 py-2 text-xs dark:bg-zinc-900 md:max-w-screen-lg"
}
>
<b>{extendedError?.category}: </b>
{extendedError?.reason}
</pre>
</>
)}
</div>
);
}