@restnfeel/agentc-starter-kit
Version:
한국어 기업용 CMS 모듈 - Task Master AI와 함께 빠르게 웹사이트를 구현할 수 있는 재사용 가능한 컴포넌트 시스템
193 lines (173 loc) • 5.33 kB
text/typescript
/**
* @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(),
};
}