Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3: Handling Errors #8

Open
wants to merge 3 commits into
base: 02-groups-and-dynamic
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions app/danger-zone/[...slug]/page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { notFound } from 'next/navigation';

export default async function Page() {
notFound();
}
22 changes: 22 additions & 0 deletions app/danger-zone/error-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use client';
import { useState } from 'react';

export default function ErrorButton() {
const [clicked, setClicked] = useState(false);

if (clicked) {
throw new Error('This is why the call it the Danger Zone.');
}

return (
<button
onClick={() => {
setClicked(true);
}}
type="button"
className="rounded-md bg-red-700 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600"
>
Throw an error!
</button>
);
}
40 changes: 40 additions & 0 deletions app/danger-zone/error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use client'; // Error components must be Client Components

import { useEffect } from 'react';

export default function Error({
error,
reset,
}: {
error: Error;
reset: () => void;
}) {
useEffect(() => {
// Log the error to an error reporting service
console.error(error.message);
}, [error]);

return (
<div>
<div className="border-b border-gray-200 pb-5 sm:flex sm:items-center sm:justify-between">
<h2 className="text-base font-semibold leading-6 text-gray-900">
Something went wrong!
</h2>
<div className="mt-3 flex sm:ml-4 sm:mt-0">
<span className="text-sm text-gray-500 italic">Oh no!</span>
</div>
</div>
<div className="p-8 bg-red-200 border border-red-600 text-red-700 font-semibold">
Error: {error.message}
<div className="mt-4">
<button
className="rounded-md bg-red-700 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600"
onClick={reset}
>
Reset
</button>
</div>
</div>
</div>
);
}
15 changes: 15 additions & 0 deletions app/danger-zone/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<div className="outline-2 outline-red-500 outline-dashed rounded-lg p-4 -mx-4">
<div className="p-4 -m-4 text-white sm:flex sm:items-center sm:justify-between mb-8">
<h2 className="text-base font-semibold leading-6 text-red-500">
The Danger Zone
</h2>
<div className="mt-3 flex sm:ml-4 sm:mt-0">
<span className="text-sm text-gray-500 italic">Yikes!</span>
</div>
</div>
{children}
</div>
);
}
19 changes: 19 additions & 0 deletions app/danger-zone/not-found.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export const metadata = {
title: `Danger Not Found`,
};

export default function NotFound() {
return (
<>
<div className="border-b border-gray-200 pb-5 sm:flex sm:items-center sm:justify-between">
<h2 className="text-base font-semibold leading-6 text-gray-900">
<span className="font-mono">Danger Not Found</span>
</h2>
<div className="mt-3 flex sm:ml-4 sm:mt-0">
<span className="text-sm text-gray-500 italic">No danger here!</span>
</div>
</div>
<div className="h-8 rounded-lg shadow bg-sky-600" />
</>
);
}
34 changes: 34 additions & 0 deletions app/danger-zone/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import Link from 'next/link';
import ErrorButton from './error-button';

export const metadata = {
title: 'Welcome to the Danger Zone!',
};

export default function Home() {
return (
<>
<div className="border-b border-gray-200 pb-5 sm:flex sm:items-center sm:justify-between">
<h2 className="text-base font-semibold leading-6 text-gray-900">
Welcome to the Danger Zone!
</h2>
<div className="mt-3 flex sm:ml-4 sm:mt-0">
<ErrorButton />
</div>
</div>
<div className="prose mt-8">
<h2>Other Errors:</h2>
<ul>
<li>
<Link href="/danger-zone/server-component-error">
Server Component Error
</Link>
</li>
<li>
<Link href="/danger-zone/sfsfsdfsdf">Not Found</Link>
</li>
</ul>
</div>
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export async function fnThatErrors() {
throw new Error('This message will not appear in production');
}
9 changes: 9 additions & 0 deletions app/danger-zone/server-component-error/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { fnThatErrors } from './function-that-errors';

export const dynamic = 'force-dynamic';

export default async function Page() {
await fnThatErrors();

return <div>This will totally work</div>;
}
79 changes: 79 additions & 0 deletions app/global-error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
'use client';
import Link from 'next/link';
import './globals.css';
import { Inter } from 'next/font/google';
const inter = Inter({ subsets: ['latin'] });
import { useEffect } from 'react';

export default function GlobalError({
error,
reset,
}: {
error: Error;
reset: () => void;
}) {
useEffect(() => {
// Log the error to an error reporting service
console.error(error);
}, [error]);

return (
<html lang="en">
<body className={inter.className}>
<div className="container p-4 mx-auto">
<header className="md:flex md:items-center md:justify-between mb-8">
<div className="min-w-0 flex-1">
<h1 className="text-2xl font-bold leading-7 text-gray-900 sm:truncate sm:text-3xl sm:tracking-tight">
Something went wrong!
</h1>
</div>
<div className="mt-4 flex md:ml-4 md:mt-0">
{new Date().toLocaleTimeString()}
</div>
</header>

<div className="p-8 bg-red-200 border border-red-600 text-red-700 font-semibold">
Error: {error.message}
</div>

<footer className="mt-8 border-t border-t-sky-500 pt-8">
<nav className="prose">
<h3>Links!</h3>
<ul>
<li>
<Link href="/">Home</Link>
</li>
<li>
<Link href="/awesome">Awesome</Link>
<ul>
<li>
<Link href="/awesome/sauce">Sauce</Link>
</li>
<li>
<Link href="/awesome/totally">Totally</Link>
</li>

<li>
<Link href="/awesome/mix">Mix</Link>
<ul>
<li>
<Link href="/awesome/mix/vol/1">Volume 1</Link>
</li>
<li>
<Link href="/awesome/mix/vol/2">Volume 2</Link>
</li>
<li>
<Link href="/awesome/mix/vol/2">Volume 2345</Link>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</footer>
</div>
</body>
</html>
);
}
3 changes: 3 additions & 0 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ export default function RootLayout({
<li>
<Link href="/interactive">Interactive</Link>
</li>
<li>
<Link href="/danger-zone">Error</Link>
</li>
<li>
<Link href="/awesome">Awesome</Link>
<ul>
Expand Down
19 changes: 19 additions & 0 deletions app/not-found.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export const metadata = {
title: `¯\_(ツ)_/¯`,
};

export default function NotFound() {
return (
<>
<div className="border-b border-gray-200 pb-5 sm:flex sm:items-center sm:justify-between">
<h2 className="text-base font-semibold leading-6 text-gray-900">
<span className="font-mono">¯\_(ツ)_/¯</span>
</h2>
<div className="mt-3 flex sm:ml-4 sm:mt-0">
<span className="text-sm text-gray-500 italic">I&apos;unno</span>
</div>
</div>
<div className="h-8 rounded-lg shadow bg-sky-600" />
</>
);
}