typescriptintermediate

Next.js Error Handling Patterns

Implement error.tsx, not-found.tsx, and global-error.tsx for comprehensive error handling.

typescript
// app/dashboard/error.tsx
'use client';

export default function DashboardError({
  error,
  reset,
}: {
  error: Error & { digest?: string };
  reset: () => void;
}) {
  return (
    <div className="flex flex-col items-center justify-center min-h-[50vh]">
      <h2 className="text-2xl font-bold mb-4">Something went wrong!</h2>
      <p className="text-gray-500 mb-4">{error.message}</p>
      <button
        onClick={reset}
        className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
      >
        Try again
      </button>
    </div>
  );
}

// app/global-error.tsx (catches root layout errors)
'use client';

export default function GlobalError({
  error,
  reset,
}: {
  error: Error & { digest?: string };
  reset: () => void;
}) {
  return (
    <html>
      <body>
        <h2>Something went wrong!</h2>
        <button onClick={reset}>Try again</button>
      </body>
    </html>
  );
}

// app/dashboard/not-found.tsx
import Link from 'next/link';

export default function NotFound() {
  return (
    <div className="text-center py-20">
      <h2 className="text-3xl font-bold mb-2">Page Not Found</h2>
      <p className="text-gray-500 mb-4">Could not find the requested resource.</p>
      <Link href="/dashboard" className="text-blue-500 underline">
        Back to Dashboard
      </Link>
    </div>
  );
}

// Trigger not-found in a server component
import { notFound } from 'next/navigation';

export default async function Page({ params }: { params: { id: string } }) {
  const item = await getItem(params.id);
  if (!item) notFound();
  return <div>{item.name}</div>;
}

Use Cases

  • Graceful error recovery in nested layouts
  • Custom 404 pages per route segment
  • Client-side error boundaries with retry

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.