243 lines
5.8 KiB
TypeScript
243 lines
5.8 KiB
TypeScript
/**
|
|
* 错误处理工具类
|
|
*
|
|
* 提供统一的错误处理、日志记录和用户友好的错误提示
|
|
*
|
|
* @author AI Chat System
|
|
* @version 1.0.0
|
|
*/
|
|
|
|
import LanguageUtils from "../../Main/Common/LanguageUtils";
|
|
import { TipsPanel } from "../ui/panels/TipsPanel";
|
|
|
|
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
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 记录错误到内部日志
|
|
*/
|
|
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:
|
|
console.error(logMessage, errorInfo.details);
|
|
break;
|
|
case ErrorType.VALIDATION_ERROR:
|
|
console.warn(logMessage, errorInfo.details);
|
|
break;
|
|
default:
|
|
console.log(logMessage, errorInfo.details);
|
|
}
|
|
|
|
// 如果有堆栈信息,也输出
|
|
if (errorInfo.stack) {
|
|
console.error("Stack trace:", errorInfo.stack);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 向用户显示友好的错误信息
|
|
*/
|
|
private showUserFriendlyError(errorInfo: ErrorInfo): void {
|
|
let userMessage: string;
|
|
|
|
TipsPanel.show(LanguageUtils.getText("chat_error_code_2005"));
|
|
|
|
// TODO: 这里应该显示UI提示,比如Toast或对话框
|
|
console.log("用户提示:", userMessage);
|
|
}
|
|
|
|
/**
|
|
* 获取错误日志
|
|
*/
|
|
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);
|
|
}
|
|
|
|
/**
|
|
* 检查是否有未处理的关键错误
|
|
*/
|
|
public hasCriticalErrors(): boolean {
|
|
const criticalTypes = [ErrorType.API_ERROR, ErrorType.CONFIG_ERROR];
|
|
return this.errorLog.some(
|
|
(error) =>
|
|
criticalTypes.includes(error.type) &&
|
|
Date.now() - error.timestamp < 60000 // 1分钟内的错误
|
|
);
|
|
}
|
|
}
|