create_and_poll 在 failed 场景下抛出 ValidationError,掩盖真实错误
- Dominant language
- Python
- Stars
- 492
- Forks
- 122
- PR merge metrics
- No merged PRs in 30d
Description
环境信息
- cozepy: 0.20.0
- pydantic: 2.12.5
- Python: 3.12
- Base URL: https://api.coze.cn
问题概述
在 `coze.chat.create_and_poll(...)` 的失败路径中,SDK 会抛出误导性的 Pydantic `ValidationError`,而不是返回 chat 的真实失败原因(`last_error.code/msg`)。
该问题会导致业务方无法直接看到真正错误(例如配额耗尽)。
---
复现 1(chat 失败:配额耗尽)
说明:该场景下 chat 可创建成功,但状态最终为 failed(例如 `last_error.code=4028`)。
```python
from cozepy import Coze, TokenAuth, Message, COZE_CN_BASE_URL
coze = Coze(auth=TokenAuth(token="YOUR_TOKEN"), base_url=COZE_CN_BASE_URL)
msg = Message.build_user_question_text('{"ping":"pong"}')
coze.chat.create_and_poll(
bot_id="YOUR_VALID_BOT_ID",
user_id="debug-user",
additional_messages=[msg],
)
```
实际结果:
- 抛出 `ValidationError`:
- `Input should be a valid dictionary or instance of Message`
- `input_value='code'`
- 典型栈在 `chat/message/list` -> `ListResponse[Message]` 解析阶段触发。
通过绕开 `create_and_poll` 验证真实状态:
```python
chat = coze.chat.create(...)
chat = coze.chat.retrieve(...)
print(chat.status, chat.last_error)
```
可以看到真实失败信息(示例):
- `status = failed`
- `last_error.code = 4028`
- `last_error.msg = "Your free quota has been used up. Please upgrade to a paid plan to continue: https://console.volcengine.com/coze-pro"`
---
复现 2(错误 bot_id)
说明:这个场景是“正常行为”。
```python
coze.chat.create_and_poll(
bot_id="1234567890123456789", # 不存在
user_id="debug-user",
additional_messages=[msg],
)
```
结果:
- 直接抛出 `CozeAPIError`
- `code = 4200`
- `msg = Requested resource bot_id=... does not exist`
这说明 SDK 在“create 请求失败”时处理正常,
问题集中在“chat 已创建但最终 failed”的 `create_and_poll` 后续处理逻辑。
---
疑似根因
`create_and_poll` 在轮询结束后,无论 `chat.status` 是否为 `failed`,都会继续调用:
- `messages.list(conversation_id=..., chat_id=...)`
当该接口返回的不是消息数组(例如错误结构 `{code, detail, msg}`)时,
SDK 仍按 `List[Message]` 做解析,最终抛出 `ValidationError`(input_value='code')。
Contributor guide
Assessment
This issue has not been assessed yet.