From 73cc4185c3fb9fd43fe51f6a47ac7d056590eeb4 Mon Sep 17 00:00:00 2001 From: Thomas Hallock Date: Thu, 20 Nov 2025 09:07:34 -0600 Subject: [PATCH] feat: add custom error boundaries with navigation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace Next.js default error boundary with custom error pages that preserve navigation and provide better UX. **Problem:** - Default Next.js error boundary shows generic message with NO navigation - Users have no way to recover or navigate away from error - Message: "Application error: a client-side exception has occurred (see the browser console for more information)." **Solution:** - Add custom error.tsx at root level with navigation links - Add custom error.tsx in /arcade with PageWithNav component - Both provide: - Clear error message - "Try Again" button to reset error boundary - Navigation links (home, arcade lobby) - Collapsible technical details for debugging **Benefits:** - Users can always navigate away from errors - Arcade errors keep the nav bar for consistent UX - Root errors provide basic navigation links - Professional error pages instead of generic Next.js message 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- apps/web/src/app/arcade/error.tsx | 191 ++++++++++++++++++++++++ apps/web/src/app/error.tsx | 237 ++++++++++++++++++++++++++++++ 2 files changed, 428 insertions(+) create mode 100644 apps/web/src/app/arcade/error.tsx create mode 100644 apps/web/src/app/error.tsx diff --git a/apps/web/src/app/arcade/error.tsx b/apps/web/src/app/arcade/error.tsx new file mode 100644 index 00000000..3149e54a --- /dev/null +++ b/apps/web/src/app/arcade/error.tsx @@ -0,0 +1,191 @@ +'use client' + +import { useEffect } from 'react' +import { PageWithNav } from '@/components/PageWithNav' +import { css } from '../../../styled-system/css' + +export default function ArcadeError({ + error, + reset, +}: { + error: Error & { digest?: string } + reset: () => void +}) { + useEffect(() => { + console.error('[Arcade Error Boundary]', error) + }, [error]) + + return ( + +
+ {/* Error icon */} +
+ ⚠️ +
+ + {/* Error title */} +

+ Something Went Wrong +

+ + {/* Error message */} +

+ The game encountered an unexpected error. You can try reloading the game, or return to the + arcade lobby. +

+ + {/* Action buttons */} +
+ + + + Return to Lobby + +
+ + {/* Technical details (collapsed by default) */} +
+ + Show technical details + + +
+
+ Error: {error.message} +
+ + {error.digest && ( +
+ Digest: {error.digest} +
+ )} + + {error.stack && ( +
+                {error.stack}
+              
+ )} +
+
+
+
+ ) +} diff --git a/apps/web/src/app/error.tsx b/apps/web/src/app/error.tsx new file mode 100644 index 00000000..09e4210e --- /dev/null +++ b/apps/web/src/app/error.tsx @@ -0,0 +1,237 @@ +'use client' + +import { useEffect } from 'react' +import { css } from '../../styled-system/css' + +export default function RootError({ + error, + reset, +}: { + error: Error & { digest?: string } + reset: () => void +}) { + useEffect(() => { + console.error('[Root Error Boundary]', error) + }, [error]) + + return ( + + +
+ {/* Error icon */} +
+ ⚠️ +
+ + {/* Error title */} +

+ Something Went Wrong +

+ + {/* Error message */} +

+ The application encountered an unexpected error. You can try reloading the page, or + return to the home page. +

+ + {/* Action buttons */} +
+ + + + Return Home + +
+ + {/* Navigation links */} + + + {/* Technical details (collapsed by default) */} +
+ + Show technical details + + +
+
+ Error: {error.message} +
+ + {error.digest && ( +
+ Digest: {error.digest} +
+ )} + + {error.stack && ( +
+                  {error.stack}
+                
+ )} +
+
+
+ + + ) +}