UNPKG

@restnfeel/agentc-starter-kit

Version:

한국어 기업용 CMS 모듈 - Task Master AI와 함께 빠르게 웹사이트를 구현할 수 있는 재사용 가능한 컴포넌트 시스템

193 lines (173 loc) 5.33 kB
/** * @fileoverview Error handling hook for the RAG chatbot system * @module hooks/useErrorHandler */ import { useCallback, useEffect, useState } from "react"; import { useChatbot } from "./useChatbot"; import type { ChatbotError } from "../core/contexts/ChatbotContext"; /** * Return type for the useErrorHandler hook */ export interface UseErrorHandlerReturn { /** Current error state */ error: ChatbotError | null; /** Whether there is an active error */ hasError: boolean; /** Clear the current error */ clearError: () => void; /** Handle a new error */ handleError: (error: Error | ChatbotError | string) => void; /** Get error display message */ getErrorMessage: () => string | null; /** Check if error is of specific type */ isErrorType: (code: string) => boolean; /** Error severity level */ errorSeverity: "low" | "medium" | "high" | null; } /** * Hook for handling errors in the chatbot system * Provides utilities for error management and user feedback * * @returns {UseErrorHandlerReturn} Error handling utilities * * @example * ```typescript * function ErrorBoundary() { * const { * error, * hasError, * clearError, * handleError, * getErrorMessage, * errorSeverity * } = useErrorHandler(); * * const handleRetry = () => { * clearError(); * // Retry the failed operation * }; * * if (hasError) { * return ( * <div className={`error error-${errorSeverity}`}> * <p>{getErrorMessage()}</p> * <button onClick={handleRetry}>Retry</button> * <button onClick={clearError}>Dismiss</button> * </div> * ); * } * * return null; * } * ``` */ export function useErrorHandler(): UseErrorHandlerReturn { const { lastError, clearError: clearChatbotError } = useChatbot(); const [localError, setLocalError] = useState<ChatbotError | null>(null); // Use chatbot error or local error const error = lastError || localError; const clearError = useCallback(() => { clearChatbotError(); setLocalError(null); }, [clearChatbotError]); const handleError = useCallback((error: Error | ChatbotError | string) => { let chatbotError: ChatbotError; if (typeof error === "string") { chatbotError = { code: "GENERIC_ERROR", message: error, timestamp: new Date(), }; } else if (error instanceof Error) { chatbotError = { code: "JAVASCRIPT_ERROR", message: error.message, details: { stack: error.stack, name: error.name }, timestamp: new Date(), }; } else { chatbotError = error; } setLocalError(chatbotError); }, []); const getErrorMessage = useCallback((): string | null => { if (!error) return null; // Map error codes to user-friendly messages const errorMessages: Record<string, string> = { INITIALIZATION_FAILED: "Failed to initialize chatbot. Please check your configuration.", VECTOR_STORE_CONNECTION_FAILED: "Cannot connect to vector database. Please check your connection.", LLM_API_ERROR: "AI service is temporarily unavailable. Please try again later.", STORAGE_UPLOAD_FAILED: "File upload failed. Please try again.", DOCUMENT_PROCESSING_FAILED: "Document processing failed. Please check the file format.", NETWORK_ERROR: "Network connection error. Please check your internet connection.", AUTHENTICATION_FAILED: "Authentication failed. Please check your API keys.", RATE_LIMIT_EXCEEDED: "Rate limit exceeded. Please wait and try again.", INVALID_CONFIGURATION: "Invalid configuration. Please check your settings.", DOCUMENT_NOT_FOUND: "Document not found.", CONVERSATION_NOT_FOUND: "Conversation not found.", GENERIC_ERROR: error.message, JAVASCRIPT_ERROR: error.message, }; return ( errorMessages[error.code] || error.message || "An unexpected error occurred." ); }, [error]); const isErrorType = useCallback( (code: string): boolean => { return error?.code === code; }, [error] ); const errorSeverity = useCallback((): "low" | "medium" | "high" | null => { if (!error) return null; const highSeverityCodes = [ "INITIALIZATION_FAILED", "AUTHENTICATION_FAILED", "VECTOR_STORE_CONNECTION_FAILED", "LLM_API_ERROR", ]; const mediumSeverityCodes = [ "STORAGE_UPLOAD_FAILED", "DOCUMENT_PROCESSING_FAILED", "NETWORK_ERROR", "INVALID_CONFIGURATION", ]; if (highSeverityCodes.includes(error.code)) { return "high"; } else if (mediumSeverityCodes.includes(error.code)) { return "medium"; } else { return "low"; } }, [error]); // Auto-clear certain errors after a timeout useEffect(() => { if ( error && ["RATE_LIMIT_EXCEEDED", "NETWORK_ERROR"].includes(error.code) ) { const timer = setTimeout(() => { clearError(); }, 5000); // Auto-clear after 5 seconds return () => clearTimeout(timer); } }, [error, clearError]); return { error, hasError: !!error, clearError, handleError, getErrorMessage, isErrorType, errorSeverity: errorSeverity(), }; }