错误处理
SDK 抛出的所有错误都继承自 OpenhexSdkError:平台拒绝请求时是带状态码的 ApiError,一轮对话等不到回复时是 AbortError,缺少凭据时是 AuthenticationError。 按类型 catch,就能区分「该重试」「该换令牌」和「该修代码」。
错误类型
| 类型 | 何时抛出 | 关键字段 |
|---|---|---|
OpenhexSdkError | 所有 SDK 错误的基类;也用于客户端侧的拒绝(例如把凭据发往其他域名) | message |
ApiError | 平台返回非 2xx | status、message(即响应里的 detail)、body |
AuthenticationError | 构造客户端时找不到凭据 | message |
AbortError | 一轮对话在限定时间内没有收到任何事件 | message |
NotImplementedError | 调用了尚未提供的入口(如 query()) | message |
import { ApiError, AbortError, AuthenticationError } from '@openhex-ai/agent-sdk';
try {
const turn = await client.sendMessage('你好');
} catch (err) {
if (err instanceof ApiError) {
console.error(err.status, err.message); // 例如 401 "invalid Bearer token"
} else if (err instanceof AbortError) {
console.error('Agent 太久没有响应');
} else if (err instanceof AuthenticationError) {
console.error('没有配置 apiKey');
} else {
throw err;
}
}
平台的错误响应统一是 { "detail": "…" },SDK 把 detail 放进 err.message,原始响应体在 err.body。
状态码怎么处理
| 状态码 | 含义 | 建议 |
|---|---|---|
400 | 请求参数不合法 | 修代码,不要重试 |
401 | 凭据缺失、无效、过期或类型不对 | 会话令牌:换一个新的再重试一次;API Key:检查配置 |
402 | 余额不足 | 提示用户,或给成员发放积分 |
403 | 凭据有效但无权操作 | 检查凭据类型、工作区是否匹配、成员是否停用 |
404 | 资源不存在,或对当前凭据不可见 | 检查 id;不要重试 |
409 | 冲突(例如 slug 已被占用) | 换一个值 |
413 | 内容过大 | 缩小内容 |
429 | 请求过于频繁 | 退避后重试 |
5xx | 平台暂时不可用 | 指数退避后重试 |
超时与取消
| 场景 | 默认 | 超时后 |
|---|---|---|
| 非流式请求(发送、历史、上传、工作区接口) | 30 秒,客户端配置 timeoutMs 可改 | 请求被中止 |
一轮对话等待事件(sendMessage / runTurn) | 连续 180 秒无事件,idleTimeoutMs 可改 | 抛出 AbortError |
读流(chat.stream) | 不超时,断线自动重连 | — |
所有方法都接受 signal,用 AbortController 主动取消。取消只停止本地等待;要让 Agent 停下,再调用 client.chat.interrupt(conversationId)。
const ac = new AbortController();
const pending = client.sendMessage('写一份长报告', { signal: ac.signal });
ac.abort(); // 不再等待
await client.chat.interrupt(conversationId); // 让 Agent 也停下
重试
- 流会自动重连。
chat.stream断线后按指数退避重连,并从最后一条记录的游标续传,不会丢也不会重复。 - 发送不会自动重试。 网络错误时,先用
chat.messages(conversationId)确认消息是否已经送达,再决定是否重发,避免同一条消息发两次。 - 需要幂等的写操作用幂等键。 例如发放积分的
idempotency_key,重放是安全的。
常见问题
构造时就报 AuthenticationError,但我明明配置了环境变量。
在浏览器里运行时没有环境变量,必须显式传入 apiKey。浏览器里应该用会话令牌,见鉴权。
sendMessage 等了很久然后 AbortError。
新对话的第一条消息要为 Agent 拉起运行环境;Agent 委派子 Agent 时也会长时间没有输出。适当调大 idleTimeoutMs。
浏览器里一直显示「正在输入」,但 Node 里正常。
检查浏览器控制台是否有跨域 (CORS) 报错。如果你通过自己的代理访问平台,确保代理对流式接口 GET /conversations/{id}/stream 返回了正确的 Access-Control-Allow-Origin,并且没有缓冲 SSE 响应。