From b5292a9ac81e4407b8151550eed75d364a2a5e22 Mon Sep 17 00:00:00 2001 From: Vu Van Dung Date: Thu, 21 Apr 2022 16:08:23 +0800 Subject: [PATCH] custom error pages Signed-off-by: Vu Van Dung --- packages/client/layouts/errors.tsx | 55 ++++++++++++++++++++++++++++++ packages/client/pages/404.tsx | 5 +++ packages/client/pages/_app.tsx | 14 +++++--- packages/client/pages/_error.tsx | 12 +++++++ 4 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 packages/client/layouts/errors.tsx create mode 100644 packages/client/pages/404.tsx create mode 100644 packages/client/pages/_error.tsx diff --git a/packages/client/layouts/errors.tsx b/packages/client/layouts/errors.tsx new file mode 100644 index 00000000..e20ea47b --- /dev/null +++ b/packages/client/layouts/errors.tsx @@ -0,0 +1,55 @@ +import Head from "next/head"; +import Image from "next/image"; +import { Component, ErrorInfo, FC, ReactNode } from "react"; + +import Button from "@client/components/buttons"; + +export const ErrorLayout: FC<{ code?: number }> = ({ code }) => { + const errors = { + 404: "The page you requested cannot be found.", + 500: "A server error occurred, and we're working on it.", + default: + "An unknown error occurred, likely a client-side error. Please see the console for details.", + }; + return ( + <> + + Error{code ? ` ${code}` : ""} | ezkomment + +
+
+ ezkomment +

{code ? code : "Error"}

+
+ {code && [404, 500].includes(code) + ? errors[code.toString() as "404" | "500"] + : errors.default} +
+ +
+
+ + ); +}; + +interface ErrorBoundaryProps { + children: ReactNode; +} +interface ErrorBoundaryState { + hasError: boolean; +} +export class ErrorBoundary extends Component { + constructor(props: ErrorBoundaryProps) { + super(props); + this.state = { hasError: false }; + } + static getDerivedStateFromError(): ErrorBoundaryState { + return { hasError: true }; + } + componentDidCatch(error: Error, errorInfo: ErrorInfo) { + console.error("Uncaught error:", error, errorInfo); + } + render() { + return this.state.hasError ? : this.props.children; + } +} diff --git a/packages/client/pages/404.tsx b/packages/client/pages/404.tsx new file mode 100644 index 00000000..1614511b --- /dev/null +++ b/packages/client/pages/404.tsx @@ -0,0 +1,5 @@ +import { ErrorLayout } from "@client/layouts/errors"; + +const Error404 = () => ; + +export default Error404; diff --git a/packages/client/pages/_app.tsx b/packages/client/pages/_app.tsx index e29c8512..8ccecbb0 100644 --- a/packages/client/pages/_app.tsx +++ b/packages/client/pages/_app.tsx @@ -7,6 +7,8 @@ import ModeContext from "@client/context/mode"; import ScreenWidthContext from "@client/context/screenWidth"; import getScreenWidth from "@client/lib/getScreenWidth"; +import { ErrorBoundary } from "@client/layouts/errors"; + import { Breakpoint, Mode } from "@client/types/utils.type"; import "@client/styles/globals.css"; @@ -51,11 +53,13 @@ function MyApp({ Component, pageProps }: AppProps) { }, [router]); return ( - - - - - + + + + + + + ); } diff --git a/packages/client/pages/_error.tsx b/packages/client/pages/_error.tsx new file mode 100644 index 00000000..4fcdd41e --- /dev/null +++ b/packages/client/pages/_error.tsx @@ -0,0 +1,12 @@ +import { NextPage } from "next"; + +import { ErrorLayout } from "@client/layouts/errors"; + +const Error: NextPage<{ code?: number }> = ({ code }) => ; + +Error.getInitialProps = ({ res, err }) => { + const code = res ? res.statusCode : err ? err.statusCode : 404; + return { code }; +}; + +export default Error;