diff --git a/src/components/ErrorBoundary.jsx b/src/components/ErrorBoundary.jsx deleted file mode 100644 index b20c0288..00000000 --- a/src/components/ErrorBoundary.jsx +++ /dev/null @@ -1,77 +0,0 @@ -import React, { useCallback, useState } from 'react'; -import { ErrorBoundary as ReactErrorBoundary } from 'react-error-boundary'; - -function ErrorFallback({ error, resetErrorBoundary, showDetails, componentStack }) { - return ( -
-
-
-
- - - -
-

- Something went wrong -

-
-
-

An error occurred while loading the chat interface.

- {showDetails && error && ( -
- Error Details -
-                {error.toString()}
-                {componentStack}
-              
-
- )} -
-
- -
-
-
- ); -} - -function ErrorBoundary({ children, showDetails = false, onRetry = undefined, resetKeys = undefined }) { - const [componentStack, setComponentStack] = useState(null); - - const handleError = useCallback((error, errorInfo) => { - console.error('ErrorBoundary caught an error:', error, errorInfo); - setComponentStack(errorInfo?.componentStack || null); - }, []); - - const handleReset = useCallback(() => { - setComponentStack(null); - onRetry?.(); - }, [onRetry]); - - const renderFallback = useCallback(({ error, resetErrorBoundary }) => ( - - ), [showDetails, componentStack]); - - return ( - - {children} - - ); -} - -export default ErrorBoundary; diff --git a/src/components/main-content/view/ErrorBoundary.tsx b/src/components/main-content/view/ErrorBoundary.tsx new file mode 100644 index 00000000..68565df6 --- /dev/null +++ b/src/components/main-content/view/ErrorBoundary.tsx @@ -0,0 +1,116 @@ +import { useCallback, useState, type ErrorInfo, type ReactNode } from 'react'; +import { + ErrorBoundary as ReactErrorBoundary, + type FallbackProps, +} from 'react-error-boundary'; + +type ErrorFallbackProps = FallbackProps & { + showDetails: boolean; + componentStack: string | null; +}; + +type ErrorBoundaryProps = { + children: ReactNode; + showDetails?: boolean; + onRetry?: () => void; + resetKeys?: unknown[]; +}; + +function formatError(error: unknown): string { + if (error instanceof Error) { + return `${error.name}: ${error.message}`; + } + + return String(error); +} + +function ErrorFallback({ + error, + resetErrorBoundary, + showDetails, + componentStack, +}: ErrorFallbackProps) { + return ( +
+
+
+
+ + + +
+

Something went wrong

+
+
+

An error occurred while loading the chat interface.

+ {showDetails && ( +
+ Error Details +
+                {formatError(error)}
+                {componentStack}
+              
+
+ )} +
+
+ +
+
+
+ ); +} + +function ErrorBoundary({ + children, + showDetails = false, + onRetry = undefined, + resetKeys = undefined, +}: ErrorBoundaryProps) { + const [componentStack, setComponentStack] = useState(null); + + const handleError = useCallback((error: Error, errorInfo: ErrorInfo) => { + console.error('ErrorBoundary caught an error:', error, errorInfo); + // Keep component stack for optional debug rendering in fallback UI. + setComponentStack(errorInfo?.componentStack ?? null); + }, []); + + const handleReset = useCallback(() => { + setComponentStack(null); + onRetry?.(); + }, [onRetry]); + + const renderFallback = useCallback( + ({ error, resetErrorBoundary }: FallbackProps) => ( + + ), + [showDetails, componentStack] + ); + + return ( + + {children} + + ); +} + +export default ErrorBoundary; diff --git a/src/components/main-content/view/MainContent.tsx b/src/components/main-content/view/MainContent.tsx index 3a030220..8cfdfb0d 100644 --- a/src/components/main-content/view/MainContent.tsx +++ b/src/components/main-content/view/MainContent.tsx @@ -4,7 +4,7 @@ import ChatInterface from '../../chat/view/ChatInterface'; import FileTree from '../../file-tree/view/FileTree'; import StandaloneShell from '../../standalone-shell/view/StandaloneShell'; import GitPanel from '../../git-panel/view/GitPanel'; -import ErrorBoundary from '../../ErrorBoundary'; +import ErrorBoundary from './ErrorBoundary'; import MainContentHeader from './subcomponents/MainContentHeader'; import MainContentStateView from './subcomponents/MainContentStateView';