diff --git a/backend/app/services/llm/adapters/baidu_adapter.py b/backend/app/services/llm/adapters/baidu_adapter.py index d2199fb..1a1ce15 100644 --- a/backend/app/services/llm/adapters/baidu_adapter.py +++ b/backend/app/services/llm/adapters/baidu_adapter.py @@ -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: diff --git a/backend/app/services/llm/adapters/doubao_adapter.py b/backend/app/services/llm/adapters/doubao_adapter.py index fe6ae12..49be4c0 100644 --- a/backend/app/services/llm/adapters/doubao_adapter.py +++ b/backend/app/services/llm/adapters/doubao_adapter.py @@ -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] diff --git a/backend/app/services/llm/adapters/minimax_adapter.py b/backend/app/services/llm/adapters/minimax_adapter.py index 0c7ca58..4c98e6c 100644 --- a/backend/app/services/llm/adapters/minimax_adapter.py +++ b/backend/app/services/llm/adapters/minimax_adapter.py @@ -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] diff --git a/backend/app/services/llm/base_adapter.py b/backend/app/services/llm/base_adapter.py index 5f95843..b3c8356 100644 --- a/backend/app/services/llm/base_adapter.py +++ b/backend/app/services/llm/base_adapter.py @@ -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" \ @@ -83,14 +96,15 @@ class BaseLLMAdapter(ABC): f"1. 稍后重试\n" \ f"2. 检查服务商状态页面\n" \ f"3. 尝试切换其他LLM提供商" - + full_message = f"{context}: {message}" if context else message - + raise LLMError( 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: