/** * @fileoverview Error Boundary component for the RAG chatbot system * @module core/providers/ErrorBoundary */ import React, { Component, ErrorInfo, ReactNode } from "react"; import type { ChatbotError } from "../contexts/ChatbotContext"; import { createChatbotError } from "../../utils"; interface Props { /** Child components */ children: ReactNode; /** Custom fallback component */ fallback?: ReactNode; /** Error callback */ onError?: (error: ChatbotError, errorInfo: ErrorInfo) => void; /** Whether to show error details in development */ showErrorDetails?: boolean; } interface State { /** Whether an error has occurred */ hasError: boolean; /** The error that occurred */ error: ChatbotError | null; /** Error boundary info */ errorInfo: ErrorInfo | null; } /** * Error Boundary component for catching and handling React errors * in the chatbot system */ export class ChatbotErrorBoundary extends Component { constructor(props: Props) { super(props); this.state = { hasError: false, error: null, errorInfo: null, }; } static getDerivedStateFromError(error: Error): Partial { // Update state so the next render will show the fallback UI const chatbotError = createChatbotError( "REACT_ERROR_BOUNDARY", error.message || "An unexpected error occurred", { originalError: error, stack: error.stack, } ); return { hasError: true, error: chatbotError, }; } componentDidCatch(error: Error, errorInfo: ErrorInfo) { const chatbotError = createChatbotError( "REACT_ERROR_BOUNDARY", error.message || "An unexpected error occurred", { originalError: error, stack: error.stack, componentStack: errorInfo.componentStack, } ); this.setState({ error: chatbotError, errorInfo, }); // Call the error callback if provided this.props.onError?.(chatbotError, errorInfo); // Log error to console in development if (process.env.NODE_ENV === "development") { console.error("ChatbotErrorBoundary caught an error:", error, errorInfo); } } handleRetry = () => { this.setState({ hasError: false, error: null, errorInfo: null, }); }; render() { const { showErrorDetails = process.env.NODE_ENV === "development" } = this.props; if (this.state.hasError) { // Custom fallback component if (this.props.fallback) { return this.props.fallback; } // Default error UI return (

Chatbot Error

{this.state.error?.message || "An unexpected error occurred"}

{showErrorDetails && this.state.error?.details && (
Error Details
                {JSON.stringify(this.state.error.details, null, 2)}
              
)}
); } return this.props.children; } } /** * Hook for using error boundary in functional components */ export const useChatbotErrorHandler = () => { const [error, setError] = React.useState(null); const handleError = React.useCallback((error: ChatbotError) => { setError(error); console.error("Chatbot error:", error); }, []); const clearError = React.useCallback(() => { setError(null); }, []); return { error, handleError, clearError, hasError: error !== null, }; }; export default ChatbotErrorBoundary;