diff --git a/app/layout.tsx b/app/layout.tsx index 51f8d0e..4a4421d 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,6 +1,7 @@ import type { Metadata } from "next"; import { Inter } from "next/font/google"; import "./globals.css"; +import ErrorBoundary from "@/components/ErrorBoundary"; const inter = Inter({ subsets: ["latin"] }); @@ -17,7 +18,9 @@ export default function RootLayout({ return ( - {children} + + {children} + ); diff --git a/components/ErrorBoundary.tsx b/components/ErrorBoundary.tsx new file mode 100644 index 0000000..6cca40a --- /dev/null +++ b/components/ErrorBoundary.tsx @@ -0,0 +1,96 @@ +"use client"; + +import React, { Component, ErrorInfo, ReactNode } from 'react'; + +interface Props { + children: ReactNode; +} + +interface State { + hasError: boolean; + error: Error | null; + errorInfo: ErrorInfo | null; +} + +class ErrorBoundary extends Component { + constructor(props: Props) { + super(props); + this.state = { hasError: false, error: null, errorInfo: null }; + } + + static getDerivedStateFromError(error: Error): State { + return { hasError: true, error, errorInfo: null }; + } + + componentDidCatch(error: Error, errorInfo: ErrorInfo) { + console.error("ErrorBoundary caught an error:", error, errorInfo); + this.setState({ errorInfo }); + } + + handleReload = () => { + window.location.reload(); + }; + + handleClearStorage = () => { + try { + localStorage.clear(); + sessionStorage.clear(); + window.location.reload(); + } catch (e) { + console.error("Failed to clear storage:", e); + window.location.reload(); + } + }; + + render() { + if (this.state.hasError) { + return ( +
+
+
+ + + +
+ +

Something went wrong

+ +

+ An error occurred while rendering the application. This might be due to corrupted data or a temporary issue. +

+ +
+ + + +
+ + {process.env.NODE_ENV === 'development' && this.state.error && ( +
+ Error Details +
+                                    {this.state.error.toString()}
+                                    {this.state.errorInfo?.componentStack}
+                                
+
+ )} +
+
+ ); + } + + return this.props.children; + } +} + +export default ErrorBoundary;