"use client"; import { Component, useState, type ReactNode } from "react"; import type { ClientErrorBoundaryFallbackProps } from "./types.js"; /** * Check if an error is a network-related error */ function isNetworkError(error: Error): boolean { return error.name === "NetworkError"; } /** * Network error fallback UI with retry functionality * Shows a connection-specific message and allows retrying via page refresh */ function NetworkErrorFallback({ error, reset, }: ClientErrorBoundaryFallbackProps): ReactNode { const [isRetrying, setIsRetrying] = useState(false); const handleRetry = (): void => { setIsRetrying(true); // Refresh the page to retry the request window.location.reload(); }; return (
{/* Simple cloud with x icon using CSS */}

Connection Error

{error.message || "Unable to connect to the server. Please check your internet connection."}

); } /** * Default fallback UI for root error boundary * This is shown when an unhandled error bubbles up to the root */ function RootErrorFallback({ error, reset, }: ClientErrorBoundaryFallbackProps): ReactNode { const isDev = process.env.NODE_ENV !== "production"; return (

Internal Server Error

An unexpected error occurred while processing your request.

{isDev && (

{error.name}: {error.message}

{error.stack && (
              {error.stack}
            
)}
)}
Go to homepage
); } interface RootErrorBoundaryState { hasError: boolean; error: Error | null; } /** * Root error boundary component * * Wraps the entire segment tree to catch any unhandled errors that bubble up. * This prevents the entire app from crashing with a white screen. * * This is a client component with an inline fallback to avoid the * "Functions cannot be passed to Client Components" RSC error. */ export class RootErrorBoundary extends Component< { children: ReactNode }, RootErrorBoundaryState > { constructor(props: { children: ReactNode }) { super(props); this.state = { hasError: false, error: null }; } static getDerivedStateFromError(error: Error): RootErrorBoundaryState { return { hasError: true, error }; } componentDidMount(): void { // Listen for popstate (back/forward navigation) to reset error state window.addEventListener("popstate", this.handlePopState); } componentWillUnmount(): void { window.removeEventListener("popstate", this.handlePopState); } componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void { console.error( "[RootErrorBoundary] Unhandled error caught:", error, errorInfo, ); } componentDidUpdate(prevProps: { children: ReactNode }): void { // Reset error state when children change (e.g., navigation) // This allows the app to recover after navigation away from an errored route if (this.state.hasError && prevProps.children !== this.props.children) { this.setState({ hasError: false, error: null }); } } handlePopState = (): void => { // Reset error state on back/forward navigation if (this.state.hasError) { this.setState({ hasError: false, error: null }); } }; reset = (): void => { this.setState({ hasError: false, error: null }); }; render(): ReactNode { if (this.state.hasError && this.state.error) { const errorInfo = { message: this.state.error.message, name: this.state.error.name, stack: this.state.error.stack, cause: this.state.error.cause, segmentId: "root", segmentType: "route" as const, }; // Use specialized fallback for network errors if (isNetworkError(this.state.error)) { return ; } return ; } return this.props.children; } }