refactor(api): 优化错误处理和日志记录

对多个模块进行了重构,以改进错误处理和日志记录机制。

主要变更包括:
- 在 `gemini_routes` 中,现在会返回更具体的错误信息,包括错误码和错误消息,而不仅仅是异常的字符串表示。
- 在 `api_client` 中,简化了 Gemini API 客户端的错误处理逻辑,移除了冗余的 `try...except` 块,让异常直接向上抛出。
- 在多个服务(如 `openai_chat_service`, `embedding_service`, `tts_service` 等)中,增加了根据配置项 `ERROR_LOG_RECORD_REQUEST_BODY` 来决定是否记录请求体的逻辑,以增强隐私和性能控制。
- 在前端 `keys_status.js` 中,更新了密钥验证结果的处理逻辑,以适应后端返回的新的错误对象结构(包含 `error_code` 和 `error_message`),并移除了冗余的 `executeVerifyAllKeys` 函数。
This commit is contained in:
snaily
2025-09-18 09:59:32 +08:00
parent 68b65814bc
commit 95b5acad66
8 changed files with 103 additions and 195 deletions
+5 -94
View File
@@ -541,30 +541,13 @@ function showVerificationResultModal(data) {
const errorGroups = {};
Object.entries(failedKeys).forEach(([key, error]) => {
// 提取错误码或使用完整错误信息作为分组键
let errorCode = error;
// 尝试提取常见的错误码模式
const errorCodePatterns = [
/status code (\d+)/,
];
for (const pattern of errorCodePatterns) {
const match = error.match(pattern);
if (match) {
errorCode = match[1] || match[0];
break;
}
}
// 如果没有匹配到特定模式,使用500
if (errorCode === error) {
errorCode = 500;
}
let errorCode = error["error_code"];
let errorMessage = error["error_message"];
if (!errorGroups[errorCode]) {
errorGroups[errorCode] = [];
}
errorGroups[errorCode].push({ key, error });
errorGroups[errorCode].push({ key, errorMessage });
});
// 创建分组展示容器
@@ -609,7 +592,7 @@ function showVerificationResultModal(data) {
const keysList = document.createElement("div");
keysList.className = "group-keys-list space-y-1";
keyErrorPairs.forEach(({ key, error }) => {
keyErrorPairs.forEach(({ key, errorMessage }) => {
const keyItem = document.createElement("div");
keyItem.className = "flex flex-col items-start bg-gray-50 p-2 rounded border";
@@ -624,7 +607,7 @@ function showVerificationResultModal(data) {
const detailsButton = document.createElement("button");
detailsButton.className = "ml-2 px-2 py-0.5 bg-red-200 hover:bg-red-300 text-red-700 text-xs rounded transition-colors";
detailsButton.innerHTML = '<i class="fas fa-info-circle mr-1"></i>详情';
detailsButton.dataset.error = error;
detailsButton.dataset.error = errorMessage;
detailsButton.onclick = (e) => {
e.stopPropagation();
const button = e.currentTarget;
@@ -984,7 +967,6 @@ function initializeGlobalBatchVerificationHandlers() {
document.getElementById("verifyModal").classList.add("hidden");
};
// executeVerifyAll 变为 initializeGlobalBatchVerificationHandlers 的局部函数
async function executeVerifyAll(type) {
closeVerifyModal();
const keysToVerify = getSelectedKeys(type);
@@ -1055,8 +1037,6 @@ function initializeGlobalBatchVerificationHandlers() {
invalid_count: Object.keys(allFailedKeys).length
});
}
// The confirmButton.onclick in showVerifyModal (defined earlier in initializeGlobalBatchVerificationHandlers)
// will correctly reference this local executeVerifyAll due to closure.
}
// --- 进度条模态框函数 ---
@@ -2548,73 +2528,4 @@ function showVerifyModalForAllKeys(allKeys) {
// 显示模态框
modalElement.classList.remove("hidden");
}
// 执行验证所有密钥
async function executeVerifyAllKeys(allKeys) {
closeVerifyModal();
// 获取批次大小
const batchSizeInput = document.getElementById("batchSize");
const batchSize = parseInt(batchSizeInput.value, 10) || 10;
// 开始批量验证
showProgressModal(`批量验证所有 ${allKeys.length} 个密钥`);
let allSuccessfulKeys = [];
let allFailedKeys = {};
let processedCount = 0;
for (let i = 0; i < allKeys.length; i += batchSize) {
const batch = allKeys.slice(i, i + batchSize);
const progressText = `正在验证批次 ${Math.floor(i / batchSize) + 1} / ${Math.ceil(allKeys.length / batchSize)} (密钥 ${i + 1}-${Math.min(i + batchSize, allKeys.length)})`;
updateProgress(i, allKeys.length, progressText);
addProgressLog(`处理批次: ${batch.length}个密钥...`);
try {
const options = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ keys: batch }),
};
const data = await fetchAPI(`/gemini/v1beta/verify-selected-keys`, options);
if (data) {
if (data.successful_keys && data.successful_keys.length > 0) {
allSuccessfulKeys = allSuccessfulKeys.concat(data.successful_keys);
addProgressLog(`✅ 批次成功: ${data.successful_keys.length}`);
}
if (data.failed_keys && Object.keys(data.failed_keys).length > 0) {
Object.assign(allFailedKeys, data.failed_keys);
addProgressLog(`❌ 批次失败: ${Object.keys(data.failed_keys).length}`, true);
}
} else {
addProgressLog(`- 批次返回空数据`, true);
}
} catch (apiError) {
addProgressLog(`❌ 批次请求失败: ${apiError.message}`, true);
// 将此批次的所有密钥标记为失败
batch.forEach(key => {
allFailedKeys[key] = apiError.message;
});
}
processedCount += batch.length;
updateProgress(processedCount, allKeys.length, progressText);
}
updateProgress(
allKeys.length,
allKeys.length,
`所有批次验证完成!`
);
// 关闭进度模态框并显示最终结果
closeProgressModal(false);
showVerificationResultModal({
successful_keys: allSuccessfulKeys,
failed_keys: allFailedKeys,
valid_count: allSuccessfulKeys.length,
invalid_count: Object.keys(allFailedKeys).length
});
}