聊天报错
This commit is contained in:
@@ -27,6 +27,8 @@ export class ApiConfig {
|
||||
private static _instance: ApiConfig;
|
||||
private config: AIConfig;
|
||||
|
||||
private baseUrl: "https://generativelanguage.googleapis.com";
|
||||
|
||||
private constructor() {
|
||||
this.initConfig();
|
||||
}
|
||||
@@ -104,6 +106,9 @@ export class ApiConfig {
|
||||
public getTimeout() {
|
||||
return this.config.timeout;
|
||||
}
|
||||
public getBaseUrl() {
|
||||
return this.baseUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证配置是否有效
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
// 首先加载 polyfills 以确保兼容性
|
||||
import "../utils/polyfills";
|
||||
import { GoogleGenAI, HarmBlockThreshold, HarmCategory } from "@google/genai";
|
||||
import {
|
||||
Chat,
|
||||
GoogleGenAI,
|
||||
HarmBlockThreshold,
|
||||
HarmCategory,
|
||||
} from "@google/genai";
|
||||
import { RoleConfigLoader } from "./RoleConfigLoader";
|
||||
import { ChatHistoryManager } from "../manager/ChatHistoryManager";
|
||||
import { ApiConfig } from "./ApiConfigLoader";
|
||||
@@ -57,8 +62,16 @@ export class ChatAIService {
|
||||
try {
|
||||
this.ai = new GoogleGenAI({
|
||||
apiKey: config.apiKey,
|
||||
httpOptions: { timeout: ApiConfig.Instance.getTimeout() },
|
||||
|
||||
httpOptions: {
|
||||
timeout: ApiConfig.Instance.getTimeout(),
|
||||
baseUrl: ApiConfig.Instance.getBaseUrl(),
|
||||
},
|
||||
});
|
||||
|
||||
console.log("-------AI 启动成功-------");
|
||||
console.log(this.ai);
|
||||
this.ai.operations;
|
||||
} catch (error) {
|
||||
TipsPanel.show(LanguageUtils.getText("chat_error_code_2001"));
|
||||
ErrorHandler.Instance.handleError(
|
||||
@@ -88,7 +101,7 @@ export class ChatAIService {
|
||||
* 创建或获取指定角色的聊天实例
|
||||
* @param roleId 角色ID
|
||||
*/
|
||||
async createOrGetChat(roleId: number): Promise<any> {
|
||||
async createOrGetChat(roleId: number): Promise<Chat> {
|
||||
if (!this.chatInstances.has(roleId)) {
|
||||
const systemInstruction = RoleConfigLoader.getRoleInstruction(roleId);
|
||||
const config = ApiConfig.Instance.getAIConfig();
|
||||
@@ -97,7 +110,7 @@ export class ChatAIService {
|
||||
let savedHistory = await ChatHistoryManager.Instance.loadChatHistory(
|
||||
roleId
|
||||
);
|
||||
let chat;
|
||||
let chat: Chat;
|
||||
if (savedHistory && savedHistory.length > 0) {
|
||||
chat = this.ai.chats.create({
|
||||
model: config.model,
|
||||
@@ -130,6 +143,7 @@ export class ChatAIService {
|
||||
},
|
||||
history: savedHistory,
|
||||
});
|
||||
console.log(chat);
|
||||
console.log(
|
||||
`Loaded ${savedHistory.length} history messages for role ${roleId}`
|
||||
);
|
||||
@@ -164,6 +178,8 @@ export class ChatAIService {
|
||||
],
|
||||
},
|
||||
});
|
||||
console.log(chat);
|
||||
|
||||
console.log(`Created new chat instance for role ${roleId}`);
|
||||
}
|
||||
|
||||
@@ -226,6 +242,7 @@ export class ChatAIService {
|
||||
|
||||
try {
|
||||
const chat = await this.createOrGetChat(roleId);
|
||||
|
||||
const response = await chat.sendMessage({
|
||||
message: message.trim(),
|
||||
});
|
||||
|
||||
@@ -124,6 +124,7 @@ export class GlobalData extends BaseData {
|
||||
|
||||
/** 超时时间(微秒) */
|
||||
public getTimeout(): number {
|
||||
//return 600000;
|
||||
return this._timeout;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { IChatService } from "./IChatService";
|
||||
|
||||
export class HttpChatService implements IChatService {
|
||||
constructor(private api = ApiClient.I) {}
|
||||
|
||||
|
||||
// 上报聊天数据
|
||||
async reqChatMsg(req: proto.cs.ICSChatMsgReq): Promise<ApiResponse<proto.cs.ICSChatMsgRes>> {
|
||||
const ep: Endpoint<proto.cs.ICSChatMsgReq, proto.cs.ICSChatMsgRes> = {
|
||||
|
||||
@@ -1,243 +1,242 @@
|
||||
/**
|
||||
* 错误处理工具类
|
||||
*
|
||||
*
|
||||
* 提供统一的错误处理、日志记录和用户友好的错误提示
|
||||
*
|
||||
*
|
||||
* @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"
|
||||
/** 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;
|
||||
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;
|
||||
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;
|
||||
/**
|
||||
* 获取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 (error.status == "FAILED_PRECONDITION") {
|
||||
//当前用户区域不支持聊天功能
|
||||
TipsPanel.show(LanguageUtils.getText("chat_error_code_2003"));
|
||||
} else if (error.message.includes("Fetch is 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
// 如果有堆栈信息,也输出
|
||||
if (errorInfo.stack) {
|
||||
console.error("Stack trace:", errorInfo.stack);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理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
|
||||
};
|
||||
/**
|
||||
* 向用户显示友好的错误信息
|
||||
*/
|
||||
private showUserFriendlyError(errorInfo: ErrorInfo): void {
|
||||
let userMessage: string;
|
||||
|
||||
this.handleError(
|
||||
new Error(errorMessage),
|
||||
ErrorType.API_ERROR,
|
||||
details,
|
||||
true
|
||||
);
|
||||
}
|
||||
TipsPanel.show(LanguageUtils.getText("chat_error_code_2005"));
|
||||
|
||||
/**
|
||||
* 处理验证错误
|
||||
*
|
||||
* @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 };
|
||||
// TODO: 这里应该显示UI提示,比如Toast或对话框
|
||||
console.log("用户提示:", userMessage);
|
||||
}
|
||||
|
||||
this.handleError(
|
||||
new Error(errorMessage),
|
||||
ErrorType.VALIDATION_ERROR,
|
||||
details,
|
||||
false
|
||||
);
|
||||
}
|
||||
/**
|
||||
* 获取错误日志
|
||||
*/
|
||||
public getErrorLog(): ErrorInfo[] {
|
||||
return [...this.errorLog];
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理网络错误
|
||||
*
|
||||
* @param {any} error - 网络错误
|
||||
* @param {string} url - 请求URL
|
||||
*/
|
||||
public handleNetworkError(error: any, url?: string): void {
|
||||
const errorMessage = "网络连接失败,请检查网络设置";
|
||||
const details = { url, networkError: error };
|
||||
/**
|
||||
* 清除错误日志
|
||||
*/
|
||||
public clearErrorLog(): void {
|
||||
this.errorLog = [];
|
||||
console.log("Error log cleared");
|
||||
}
|
||||
|
||||
this.handleError(
|
||||
new Error(errorMessage),
|
||||
ErrorType.NETWORK_ERROR,
|
||||
details,
|
||||
true
|
||||
);
|
||||
}
|
||||
/**
|
||||
* 获取特定类型的错误
|
||||
*/
|
||||
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:
|
||||
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;
|
||||
|
||||
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或对话框
|
||||
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分钟内的错误
|
||||
);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 检查是否有未处理的关键错误
|
||||
*/
|
||||
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分钟内的错误
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
+1
-1
Submodule xchat_cfg updated: 53e277f100...1f0659bc5d
Reference in New Issue
Block a user