mirror of
https://github.com/snailyp/gemini-balance.git
synced 2026-09-04 23:19:17 +08:00
feat(error_handling): 增强 API 错误处理和日志记录
- 扩展 ErrorLog 数据模型,增加 model_name, error_type, error_code 字段,以记录更详细的错误信息。 - 在 GeminiChatService 和 OpenAIChatService 中添加了 try-except 块,用于捕获 API 调用(包括普通和流式调用)时发生的异常。 - 实现从异常消息中通过正则表达式提取 HTTP 状态码的功能。 - 调用 add_error_log 服务将详细的错误信息(包括模型、错误类型、代码、请求体)持久化到数据库。 - 更新了 error_logs 前端页面,增加显示模型名称列及详情。 - 优化数据库连接池配置 (pool_recycle=3600),提高连接稳定性。
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
# app/services/chat_service.py
|
||||
|
||||
import json
|
||||
import re
|
||||
from typing import Any, AsyncGenerator, Dict, List
|
||||
|
||||
from app.config.config import settings
|
||||
@@ -10,6 +11,7 @@ from app.handler.stream_optimizer import gemini_optimizer
|
||||
from app.log.logger import get_gemini_logger
|
||||
from app.service.client.api_client import GeminiApiClient
|
||||
from app.service.key.key_manager import KeyManager
|
||||
from app.database.services import add_error_log
|
||||
|
||||
logger = get_gemini_logger()
|
||||
|
||||
@@ -145,8 +147,27 @@ class GeminiChatService:
|
||||
) -> Dict[str, Any]:
|
||||
"""生成内容"""
|
||||
payload = _build_payload(model, request)
|
||||
response = await self.api_client.generate_content(payload, model, api_key)
|
||||
return self.response_handler.handle_response(response, model, stream=False)
|
||||
try:
|
||||
response = await self.api_client.generate_content(payload, model, api_key)
|
||||
return self.response_handler.handle_response(response, model, stream=False)
|
||||
except Exception as e:
|
||||
logger.error(f"Normal API call failed with error: {str(e)}")
|
||||
error_code = None
|
||||
error_log_msg = str(e)
|
||||
# 尝试从异常消息中解析状态码
|
||||
match = re.search(r"status code (\d+)", error_log_msg)
|
||||
if match:
|
||||
error_code = int(match.group(1))
|
||||
|
||||
await add_error_log(
|
||||
gemini_key=api_key,
|
||||
model_name=model,
|
||||
error_type="gemini_chat_service",
|
||||
error_log=error_log_msg,
|
||||
error_code=error_code,
|
||||
request_msg=payload
|
||||
)
|
||||
raise e # 重新抛出异常,以便上层处理
|
||||
|
||||
async def stream_generate_content(
|
||||
self, model: str, request: GeminiRequest, api_key: str
|
||||
@@ -185,9 +206,25 @@ class GeminiChatService:
|
||||
break
|
||||
except Exception as e:
|
||||
retries += 1
|
||||
error_log_msg = str(e)
|
||||
logger.warning(
|
||||
f"Streaming API call failed with error: {str(e)}. Attempt {retries} of {max_retries}"
|
||||
f"Streaming API call failed with error: {error_log_msg}. Attempt {retries} of {max_retries}"
|
||||
)
|
||||
# 解析错误信息并记录到数据库
|
||||
error_code = None
|
||||
match = re.search(r"status code (\d+)", error_log_msg)
|
||||
if match:
|
||||
error_code = int(match.group(1))
|
||||
|
||||
await add_error_log(
|
||||
gemini_key=api_key,
|
||||
model_name=model,
|
||||
error_log=error_log_msg,
|
||||
error_code=error_code,
|
||||
request_msg=payload
|
||||
)
|
||||
|
||||
# 尝试切换 API Key
|
||||
api_key = await self.key_manager.handle_api_failure(api_key)
|
||||
logger.info(f"Switched to new API key: {api_key}")
|
||||
if retries >= max_retries:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# app/services/chat_service.py
|
||||
|
||||
import json
|
||||
import re
|
||||
from copy import deepcopy
|
||||
from typing import Any, AsyncGenerator, Dict, List, Optional, Union
|
||||
|
||||
@@ -13,6 +14,7 @@ from app.log.logger import get_openai_logger
|
||||
from app.service.client.api_client import GeminiApiClient
|
||||
from app.service.image.image_create_service import ImageCreateService
|
||||
from app.service.key.key_manager import KeyManager
|
||||
from app.database.services import add_error_log
|
||||
|
||||
logger = get_openai_logger()
|
||||
|
||||
@@ -189,10 +191,28 @@ class OpenAIChatService:
|
||||
self, model: str, payload: Dict[str, Any], api_key: str
|
||||
) -> Dict[str, Any]:
|
||||
"""处理普通聊天完成"""
|
||||
response = await self.api_client.generate_content(payload, model, api_key)
|
||||
return self.response_handler.handle_response(
|
||||
response, model, stream=False, finish_reason="stop"
|
||||
)
|
||||
try:
|
||||
response = await self.api_client.generate_content(payload, model, api_key)
|
||||
return self.response_handler.handle_response(
|
||||
response, model, stream=False, finish_reason="stop"
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Normal API call failed with error: {str(e)}")
|
||||
error_code = None
|
||||
error_log_msg = str(e)
|
||||
# 尝试从异常消息中解析状态码
|
||||
match = re.search(r"status code (\d+)", error_log_msg)
|
||||
if match:
|
||||
error_code = int(match.group(1))
|
||||
|
||||
await add_error_log(
|
||||
gemini_key=api_key,
|
||||
model_name=model,
|
||||
error_log=error_log_msg,
|
||||
error_code=error_code,
|
||||
request_msg=payload
|
||||
)
|
||||
raise e # 重新抛出异常,以便上层处理
|
||||
|
||||
async def _handle_stream_completion(
|
||||
self, model: str, payload: Dict[str, Any], api_key: str
|
||||
@@ -241,9 +261,26 @@ class OpenAIChatService:
|
||||
break # 成功后退出循环
|
||||
except Exception as e:
|
||||
retries += 1
|
||||
error_log_msg = str(e)
|
||||
logger.warning(
|
||||
f"Streaming API call failed with error: {str(e)}. Attempt {retries} of {max_retries}"
|
||||
f"Streaming API call failed with error: {error_log_msg}. Attempt {retries} of {max_retries}"
|
||||
)
|
||||
# 解析错误信息并记录到数据库
|
||||
error_code = None
|
||||
match = re.search(r"status code (\d+)", error_log_msg)
|
||||
if match:
|
||||
error_code = int(match.group(1))
|
||||
print(model)
|
||||
await add_error_log(
|
||||
gemini_key=api_key,
|
||||
model_name=model,
|
||||
error_type="openai_chat_service",
|
||||
error_log=error_log_msg,
|
||||
error_code=error_code,
|
||||
request_msg=payload
|
||||
)
|
||||
|
||||
# 尝试切换 API Key
|
||||
api_key = await self.key_manager.handle_api_failure(api_key)
|
||||
logger.info(f"Switched to new API key: {api_key}")
|
||||
if retries >= max_retries:
|
||||
|
||||
Reference in New Issue
Block a user