Skip to content

Commit

Permalink
custom error pages
Browse files Browse the repository at this point in the history
Signed-off-by: Vu Van Dung <joulev.vvd@yahoo.com>
  • Loading branch information
joulev committed Apr 21, 2022
1 parent 1b44f7f commit b5292a9
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 5 deletions.
55 changes: 55 additions & 0 deletions 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 (
<>
<Head>
<title>Error{code ? ` ${code}` : ""} | ezkomment</title>
</Head>
<main className="h-screen grid place-items-center">
<div className="flex flex-col items-center gap-6 max-w-md">
<Image src="/images/logo.svg" alt="ezkomment" width={80} height={80} />
<h1 className="my-0">{code ? code : "Error"}</h1>
<div className="text-center">
{code && [404, 500].includes(code)
? errors[code.toString() as "404" | "500"]
: errors.default}
</div>
<Button href="/">Return to home</Button>
</div>
</main>
</>
);
};

interface ErrorBoundaryProps {
children: ReactNode;
}
interface ErrorBoundaryState {
hasError: boolean;
}
export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
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 ? <ErrorLayout /> : this.props.children;
}
}
5 changes: 5 additions & 0 deletions packages/client/pages/404.tsx
@@ -0,0 +1,5 @@
import { ErrorLayout } from "@client/layouts/errors";

const Error404 = () => <ErrorLayout code={404} />;

export default Error404;
14 changes: 9 additions & 5 deletions packages/client/pages/_app.tsx
Expand Up @@ -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";
Expand Down Expand Up @@ -51,11 +53,13 @@ function MyApp({ Component, pageProps }: AppProps) {
}, [router]);

return (
<ModeContext.Provider value={{ mode, setMode }}>
<ScreenWidthContext.Provider value={screenWidth}>
<Component {...pageProps} />
</ScreenWidthContext.Provider>
</ModeContext.Provider>
<ErrorBoundary>
<ModeContext.Provider value={{ mode, setMode }}>
<ScreenWidthContext.Provider value={screenWidth}>
<Component {...pageProps} />
</ScreenWidthContext.Provider>
</ModeContext.Provider>
</ErrorBoundary>
);
}

Expand Down
12 changes: 12 additions & 0 deletions 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 }) => <ErrorLayout code={code} />;

Error.getInitialProps = ({ res, err }) => {
const code = res ? res.statusCode : err ? err.statusCode : 404;
return { code };
};

export default Error;

0 comments on commit b5292a9

Please sign in to comment.