fix(llm): 增强API错误处理以包含原始响应信息
改进所有LLM适配器的错误处理逻辑,现在会捕获并传递API原始响应信息 添加对账户余额不足等特定错误类型的识别和处理 统一各适配器的错误响应格式,包含错误代码和消息
This commit is contained in:
parent
333be11edf
commit
9fe15f0d0b
|
|
@ -75,7 +75,8 @@ class BaiduAdapter(BaseLLMAdapter):
|
|||
await self.validate_config()
|
||||
return await self.retry(lambda: self._send_request(request))
|
||||
except Exception as error:
|
||||
self.handle_error(error, "百度文心一言 API调用失败")
|
||||
api_response = getattr(error, 'api_response', None)
|
||||
self.handle_error(error, "百度文心一言 API调用失败", api_response=api_response)
|
||||
|
||||
async def _send_request(self, request: LLMRequest) -> LLMResponse:
|
||||
"""发送请求"""
|
||||
|
|
@ -107,12 +108,19 @@ class BaiduAdapter(BaseLLMAdapter):
|
|||
if response.status_code != 200:
|
||||
error_data = response.json() if response.text else {}
|
||||
error_msg = error_data.get("error_msg", f"HTTP {response.status_code}")
|
||||
raise Exception(f"{error_msg}")
|
||||
error_code = error_data.get("error_code", "")
|
||||
api_response = f"[{error_code}] {error_msg}" if error_code else error_msg
|
||||
err = LLMError(error_msg, self.config.provider, response.status_code, api_response=api_response)
|
||||
raise err
|
||||
|
||||
data = response.json()
|
||||
|
||||
if "error_code" in data:
|
||||
raise Exception(f"百度API错误: {data.get('error_msg', '未知错误')}")
|
||||
error_msg = data.get('error_msg', '未知错误')
|
||||
error_code = data.get('error_code', '')
|
||||
api_response = f"[{error_code}] {error_msg}"
|
||||
err = LLMError(f"百度API错误: {error_msg}", self.config.provider, api_response=api_response)
|
||||
raise err
|
||||
|
||||
usage = None
|
||||
if "usage" in data:
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ class DoubaoAdapter(BaseLLMAdapter):
|
|||
await self.validate_config()
|
||||
return await self.retry(lambda: self._send_request(request))
|
||||
except Exception as error:
|
||||
self.handle_error(error, "豆包 API调用失败")
|
||||
api_response = getattr(error, 'api_response', None)
|
||||
self.handle_error(error, "豆包 API调用失败", api_response=api_response)
|
||||
|
||||
async def _send_request(self, request: LLMRequest) -> LLMResponse:
|
||||
"""发送请求"""
|
||||
|
|
@ -50,8 +51,12 @@ class DoubaoAdapter(BaseLLMAdapter):
|
|||
|
||||
if response.status_code != 200:
|
||||
error_data = response.json() if response.text else {}
|
||||
error_msg = error_data.get("error", {}).get("message", f"HTTP {response.status_code}")
|
||||
raise Exception(f"{error_msg}")
|
||||
error_obj = error_data.get("error", {})
|
||||
error_msg = error_obj.get("message", f"HTTP {response.status_code}")
|
||||
error_code = error_obj.get("code", "")
|
||||
api_response = f"[{error_code}] {error_msg}" if error_code else error_msg
|
||||
err = LLMError(error_msg, self.config.provider, response.status_code, api_response=api_response)
|
||||
raise err
|
||||
|
||||
data = response.json()
|
||||
choice = data.get("choices", [{}])[0]
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ class MinimaxAdapter(BaseLLMAdapter):
|
|||
await self.validate_config()
|
||||
return await self.retry(lambda: self._send_request(request))
|
||||
except Exception as error:
|
||||
self.handle_error(error, "MiniMax API调用失败")
|
||||
api_response = getattr(error, 'api_response', None)
|
||||
self.handle_error(error, "MiniMax API调用失败", api_response=api_response)
|
||||
|
||||
async def _send_request(self, request: LLMRequest) -> LLMResponse:
|
||||
"""发送请求"""
|
||||
|
|
@ -47,15 +48,23 @@ class MinimaxAdapter(BaseLLMAdapter):
|
|||
|
||||
if response.status_code != 200:
|
||||
error_data = response.json() if response.text else {}
|
||||
error_msg = error_data.get("base_resp", {}).get("status_msg", f"HTTP {response.status_code}")
|
||||
raise Exception(f"{error_msg}")
|
||||
base_resp = error_data.get("base_resp", {})
|
||||
error_msg = base_resp.get("status_msg", f"HTTP {response.status_code}")
|
||||
error_code = base_resp.get("status_code", "")
|
||||
api_response = f"[{error_code}] {error_msg}" if error_code else error_msg
|
||||
err = LLMError(error_msg, self.config.provider, response.status_code, api_response=api_response)
|
||||
raise err
|
||||
|
||||
data = response.json()
|
||||
|
||||
# MiniMax 特殊的错误处理
|
||||
if data.get("base_resp", {}).get("status_code") != 0:
|
||||
error_msg = data.get("base_resp", {}).get("status_msg", "未知错误")
|
||||
raise Exception(f"MiniMax API错误: {error_msg}")
|
||||
base_resp = data.get("base_resp", {})
|
||||
if base_resp.get("status_code") != 0:
|
||||
error_msg = base_resp.get("status_msg", "未知错误")
|
||||
error_code = base_resp.get("status_code", "")
|
||||
api_response = f"[{error_code}] {error_msg}"
|
||||
err = LLMError(f"MiniMax API错误: {error_msg}", self.config.provider, api_response=api_response)
|
||||
raise err
|
||||
|
||||
choice = data.get("choices", [{}])[0]
|
||||
|
||||
|
|
|
|||
|
|
@ -57,17 +57,30 @@ class BaseLLMAdapter(ABC):
|
|||
self.config.provider
|
||||
)
|
||||
|
||||
def handle_error(self, error: Any, context: str = "") -> None:
|
||||
"""处理API错误"""
|
||||
def handle_error(self, error: Any, context: str = "", api_response: str = None) -> None:
|
||||
"""处理API错误
|
||||
|
||||
Args:
|
||||
error: 原始异常
|
||||
context: 错误上下文描述
|
||||
api_response: API 服务器返回的原始响应信息
|
||||
"""
|
||||
message = str(error)
|
||||
status_code = getattr(error, 'status_code', None)
|
||||
|
||||
# 如果错误本身已经有 api_response,优先使用
|
||||
if api_response is None:
|
||||
api_response = getattr(error, 'api_response', None)
|
||||
|
||||
# 针对不同错误类型提供更详细的信息
|
||||
if "超时" in message or "timeout" in message.lower():
|
||||
message = f"请求超时 ({self.config.timeout}s)。建议:\n" \
|
||||
f"1. 检查网络连接是否正常\n" \
|
||||
f"2. 尝试增加超时时间\n" \
|
||||
f"3. 验证API端点是否正确"
|
||||
elif any(keyword in message for keyword in ["余额不足", "资源包", "充值", "quota", "insufficient", "balance"]):
|
||||
message = f"账户余额不足或配额已用尽,请充值后重试"
|
||||
status_code = status_code or 402
|
||||
elif status_code == 401 or status_code == 403:
|
||||
message = f"API认证失败。建议:\n" \
|
||||
f"1. 检查API Key是否正确配置\n" \
|
||||
|
|
@ -90,7 +103,8 @@ class BaseLLMAdapter(ABC):
|
|||
full_message,
|
||||
self.config.provider,
|
||||
status_code,
|
||||
error
|
||||
error,
|
||||
api_response=api_response
|
||||
)
|
||||
|
||||
async def retry(self, fn, max_attempts: int = 3, delay: float = 1.0) -> Any:
|
||||
|
|
|
|||
Loading…
Reference in New Issue