diff --git a/app/w/[id]/workflow.tsx b/app/w/[id]/workflow.tsx index fcd88c2b8e..a62ee1b54a 100644 --- a/app/w/[id]/workflow.tsx +++ b/app/w/[id]/workflow.tsx @@ -18,6 +18,7 @@ import { useWorkflowRegistry } from '@/stores/workflow/registry/store' import { useWorkflowStore } from '@/stores/workflow/store' import { NotificationList } from '@/app/w/components/notifications/notifications' import { getBlock } from '../../../blocks' +import { ErrorBoundary } from '../components/error-boundary/error-boundary' import { CustomEdge } from './components/custom-edge/custom-edge' import { WorkflowBlock } from './components/workflow-block/workflow-block' import { LoopInput } from './components/workflow-loop/components/loop-input/loop-input' @@ -338,7 +339,9 @@ function WorkflowContent() { export default function Workflow() { return ( - + + + ) } diff --git a/app/w/components/error-boundary/error-boundary.tsx b/app/w/components/error-boundary/error-boundary.tsx new file mode 100644 index 0000000000..7dcea32cf7 --- /dev/null +++ b/app/w/components/error-boundary/error-boundary.tsx @@ -0,0 +1,48 @@ +'use client' + +import { Component, ReactNode } from 'react' +import { BotIcon } from 'lucide-react' +import { Card } from '@/components/ui/card' + +interface Props { + children: ReactNode + fallback?: ReactNode +} + +interface State { + hasError: boolean + error?: Error +} + +export class ErrorBoundary extends Component { + public state: State = { + hasError: false, + } + + public static getDerivedStateFromError(error: Error): State { + return { hasError: true, error } + } + + public render() { + if (this.state.hasError) { + return ( + this.props.fallback || ( +
+ +
+ +
+

Workflow Error

+

+ This workflow encountered an error and is currently unavailable. Please try again + later or create a new workflow. +

+
+
+ ) + ) + } + + return this.props.children + } +} diff --git a/app/w/error.tsx b/app/w/error.tsx new file mode 100644 index 0000000000..a2f876dfcb --- /dev/null +++ b/app/w/error.tsx @@ -0,0 +1,38 @@ +'use client' + +import { useEffect } from 'react' +import { BotIcon } from 'lucide-react' +import { Card } from '@/components/ui/card' + +interface ErrorProps { + error: Error & { digest?: string } + reset: () => void +} + +export default function Error({ error, reset }: ErrorProps) { + useEffect(() => { + // Optionally log the error to an error reporting service + console.error('Workflow error:', error) + }, [error]) + + return ( +
+ +
+ +
+

Workflow Error

+

+ This workflow encountered an error and is currently unavailable. Please try again later or + create a new workflow. +

+ +
+
+ ) +} diff --git a/app/w/global-error.tsx b/app/w/global-error.tsx new file mode 100644 index 0000000000..021c162fd9 --- /dev/null +++ b/app/w/global-error.tsx @@ -0,0 +1,41 @@ +'use client' + +import { useEffect } from 'react' +import { BotIcon } from 'lucide-react' +import { Card } from '@/components/ui/card' + +export default function GlobalError({ + error, + reset, +}: { + error: Error & { digest?: string } + reset: () => void +}) { + useEffect(() => { + console.error('Global workspace error:', error) + }, [error]) + + return ( + + +
+ +
+ +
+

Application Error

+

+ Something went wrong with the application. Please try again later. +

+ +
+
+ + + ) +} diff --git a/app/w/layout.tsx b/app/w/layout.tsx index cbdce92d4b..823ed4f967 100644 --- a/app/w/layout.tsx +++ b/app/w/layout.tsx @@ -1,6 +1,7 @@ import { Chat } from './components/chat/chat' import { Console } from './components/console/console' import { ControlBar } from './components/control-bar/control-bar' +import { ErrorBoundary } from './components/error-boundary/error-boundary' import { Sidebar } from './components/sidebar/sidebar' import { Toolbar } from './components/toolbar/toolbar' import Providers from './providers' @@ -19,7 +20,7 @@ export default function WorkspaceLayout({ children }: { children: React.ReactNod
- {children} + {children}