/** * 错误处理工具类 * * 提供统一的错误处理、日志记录和用户友好的错误提示 * * @author AI Chat System * @version 1.0.0 */ import LanguageUtils from "../../Main/Common/LanguageUtils"; import { TipsPanel } from "../ui/panels/TipsPanel"; import { logger } from "db://assets/Scripts/Main/Common/Logger"; export enum ErrorType { /** API调用错误 */ API_ERROR = "API_ERROR", /** 网络连接错误 */ NETWORK_ERROR = "NETWORK_ERROR", /** 配置错误 */ CONFIG_ERROR = "CONFIG_ERROR", /** 数据验证错误 */ VALIDATION_ERROR = "VALIDATION_ERROR", /** 存储错误 */ STORAGE_ERROR = "STORAGE_ERROR", /** 未知错误 */ UNKNOWN_ERROR = "UNKNOWN_ERROR", } export interface ErrorInfo { type: ErrorType; message: string; code?: string | number; details?: any; timestamp: number; stack?: string; } /** * 错误处理管理器 */ export class ErrorHandler { private static _instance: ErrorHandler; private errorLog: ErrorInfo[] = []; private readonly MAX_LOG_SIZE = 100; /** * 获取ErrorHandler的单例实例 */ public static get Instance(): ErrorHandler { if (!this._instance) { this._instance = new ErrorHandler(); } return this._instance; } private constructor() {} /** * 处理错误 * * @param {Error | string} error - 错误对象或错误消息 * @param {ErrorType} type - 错误类型 * @param {any} details - 错误详情 * @param {boolean} showToUser - 是否向用户显示错误 */ public handleError( error: Error | string, type: ErrorType = ErrorType.UNKNOWN_ERROR, details?: any, showToUser: boolean = false ): void { const errorInfo: ErrorInfo = { type, message: typeof error === "string" ? error : error.message, details, timestamp: Date.now(), stack: error instanceof Error ? error.stack : undefined, }; // 记录到日志 this.logError(errorInfo); // 输出到控制台 this.logToConsole(errorInfo); // 如果需要,向用户显示友好的错误信息 if (showToUser) { this.showUserFriendlyError(errorInfo); } } /** * 处理API错误 * * @param {any} error - API错误 * @param {string} apiName - API名称 * @param {any} requestData - 请求数据 */ public handleApiError(error: any, apiName: string, requestData?: any): void { const errorMessage = `API调用失败: ${apiName}`; const details = { apiName, requestData, responseError: error, }; if (details.responseError.message.includes("FAILED_PRECONDITION")) { //当前用户区域不支持聊天功能 TipsPanel.show(LanguageUtils.getText("chat_error_code_2003")); } else if (error.message.includes("aborted")) { TipsPanel.show(LanguageUtils.getText("chat_error_code_2004")); } else { this.handleError( new Error(errorMessage), ErrorType.API_ERROR, details, true ); } } /** * 处理验证错误 * * @param {string} field - 字段名 * @param {string} message - 错误消息 * @param {any} value - 无效值 */ public handleValidationError( field: string, message: string, value?: any ): void { const errorMessage = `数据验证失败: ${field} - ${message}`; const details = { field, value, validationMessage: message }; this.handleError( new Error(errorMessage), ErrorType.VALIDATION_ERROR, details, false ); } /** * 处理网络错误 * * @param {any} error - 网络错误 * @param {string} url - 请求URL */ public handleNetworkError(error: any, url?: string): void { const errorMessage = "网络连接失败,请检查网络设置"; const details = { url, networkError: error }; this.handleError( new Error(errorMessage), ErrorType.NETWORK_ERROR, details, true ); } /** * 获取错误日志 */ public getErrorLog(): ErrorInfo[] { return [...this.errorLog]; } /** * 清除错误日志 */ public clearErrorLog(): void { this.errorLog = []; console.log("Error log cleared"); } /** * 获取特定类型的错误 */ public getErrorsByType(type: ErrorType): ErrorInfo[] { return this.errorLog.filter((error) => error.type === type); } /** * 记录错误到内部日志 */ private logError(errorInfo: ErrorInfo): void { this.errorLog.push(errorInfo); // 限制日志大小 if (this.errorLog.length > this.MAX_LOG_SIZE) { this.errorLog.shift(); } } /** * 输出错误到控制台 */ private logToConsole(errorInfo: ErrorInfo): void { const logMessage = `[${errorInfo.type}] ${errorInfo.message}`; switch (errorInfo.type) { case ErrorType.API_ERROR: case ErrorType.NETWORK_ERROR: logger.error(logMessage, errorInfo.details); break; case ErrorType.VALIDATION_ERROR: logger.warn(logMessage, errorInfo.details); break; default: logger.log(logMessage, errorInfo.details); } // 如果有堆栈信息,也输出 if (errorInfo.stack) { logger.error("Stack trace:", errorInfo.stack); } } /** * 向用户显示友好的错误信息 */ private showUserFriendlyError(errorInfo: ErrorInfo): void { let userMessage: string; switch (errorInfo.type) { case ErrorType.API_ERROR: userMessage = "AI服务暂时不可用,请稍后再试"; break; case ErrorType.NETWORK_ERROR: userMessage = "网络连接失败,请检查网络设置"; break; case ErrorType.CONFIG_ERROR: userMessage = "系统配置错误,请联系管理员"; break; case ErrorType.STORAGE_ERROR: userMessage = "数据保存失败,请重试"; break; default: userMessage = "发生了未知错误,请重试或联系客服"; } // TODO: 这里应该显示UI提示,比如Toast或对话框 logger.log("用户提示:", userMessage); } }