From 6b200fd36bd63e7e2d3d021a83d8113092920f1d Mon Sep 17 00:00:00 2001 From: jimmyzhuu Date: Wed, 29 Apr 2026 16:24:37 +0800 Subject: [PATCH] fix: handle qianfan error responses --- models/qianfan/qianfan_bot.py | 60 ++++++++++++++++++++++------------ tests/test_qianfan_provider.py | 21 ++++++++++++ 2 files changed, 60 insertions(+), 21 deletions(-) diff --git a/models/qianfan/qianfan_bot.py b/models/qianfan/qianfan_bot.py index 8e7fe687..0896611a 100644 --- a/models/qianfan/qianfan_bot.py +++ b/models/qianfan/qianfan_bot.py @@ -129,29 +129,47 @@ class QianfanBot(Bot, OpenAICompatibleBot): "completion_tokens": data["usage"]["completion_tokens"], "content": data["choices"][0]["message"]["content"], } - - error = response.json().get("error", {}) - logger.error( - "[QIANFAN] chat failed, status_code={}, msg={}".format( - response.status_code, error.get("message") - ) - ) - result = {"completion_tokens": 0, "content": "提问太快啦,请休息一下再问我吧"} - need_retry = False - if response.status_code >= 500: - need_retry = retry_count < 2 - elif response.status_code == 401: - result["content"] = "授权失败,请检查 Qianfan API Key 是否正确" - elif response.status_code == 429: - result["content"] = "请求过于频繁,请稍后再试" - need_retry = retry_count < 2 - - if need_retry: - time.sleep(3) - return self.reply_text(session, args, retry_count + 1) - return result + return self._error_result(response, session, args, retry_count) except Exception as e: logger.exception(e) if retry_count < 2: return self.reply_text(session, args, retry_count + 1) return {"completion_tokens": 0, "content": "我现在有点累了,等会再来吧"} + + def _error_result(self, response, session, args=None, retry_count=0): + try: + body = response.json() + except ValueError: + body = {"raw": response.text} + + error = body.get("error") if isinstance(body, dict) else None + if isinstance(error, dict): + message = error.get("message") or str(error) + elif error: + message = str(error) + elif isinstance(body, dict) and body.get("raw") is not None: + message = str(body.get("raw")) + else: + message = str(body) + + logger.error( + "[QIANFAN] chat failed, status_code={}, msg={}".format( + response.status_code, message + ) + ) + + if response.status_code >= 500 and retry_count < 2: + time.sleep(3) + return self.reply_text(session, args, retry_count + 1) + + if response.status_code == 401: + content = "授权失败,请检查 Qianfan API Key 是否正确" + elif response.status_code == 429: + if retry_count < 2: + time.sleep(3) + return self.reply_text(session, args, retry_count + 1) + content = "请求过于频繁,请稍后再试" + else: + content = "请求失败:{}".format(message) + + return {"completion_tokens": 0, "content": content} diff --git a/tests/test_qianfan_provider.py b/tests/test_qianfan_provider.py index b4e5f522..115e7159 100644 --- a/tests/test_qianfan_provider.py +++ b/tests/test_qianfan_provider.py @@ -192,6 +192,27 @@ class TestQianfanBot(unittest.TestCase): self.assertEqual(result["completion_tokens"], 0) self.assertEqual(result["content"], "授权失败,请检查 Qianfan API Key 是否正确") + def test_reply_text_returns_raw_message_for_non_json_error(self): + fake_conf = self._fake_conf() + fake_response = MagicMock() + fake_response.status_code = 400 + fake_response.json.side_effect = ValueError + fake_response.text = "bad gateway text" + session = MagicMock() + session.messages = [{"role": "user", "content": "你好"}] + + with patch("models.qianfan.qianfan_bot.conf", return_value=fake_conf): + with patch("models.qianfan.qianfan_bot.SessionManager"): + from models.qianfan.qianfan_bot import QianfanBot + + bot = QianfanBot() + with patch("models.qianfan.qianfan_bot.requests.post", return_value=fake_response) as post: + result = bot.reply_text(session) + + self.assertEqual(result["completion_tokens"], 0) + self.assertEqual(result["content"], "请求失败:bad gateway text") + post.assert_called_once() + if __name__ == "__main__": unittest.main()