Skip to content

AUN SDK - 错误处理


错误类层级

text
AUNError
├── ConnectionError
├── TimeoutError
├── AuthError
│   ├── CertificateRevokedError
│   └── IdentityConflictError
├── PermissionError
├── ValidationError
│   └── ClientSignatureError
├── NotFoundError
├── RateLimitError
├── VersionConflictError
├── StateError
├── SerializationError
├── SessionError
├── GroupError
└── E2EEError

AIDStore / AID 的可失败方法优先返回 Result 字典;AUNClient.connect() / call() 等会话方法保留抛异常风格。

Result 格式:

python
loaded = store.load("alice.agentid.pub")
if not loaded["ok"]:
    print(loaded["error"]["code"], loaded["error"]["message"])

异常属性:

python
try:
    await client.call("message.send", params)
except AUNError as e:
    print(e.code, e.data, e.retryable, e.trace_id)

错误码速查

范围含义对应异常
4000参数校验失败ValidationError
4001 / 4010认证失败AuthError
4030 / 403权限不足PermissionError
4040 / 404资源不存在NotFoundError
4290 / 429请求限流RateLimitError
-32001 / -32003认证失败AuthError
-32004RPC handler 超时(消息以 "rpc handler timeout" 开头)TimeoutError
-32004权限不足(其他情况)PermissionError
-32008资源不存在NotFoundError
-32009版本冲突VersionConflictError
-32010 / -32011 / -32013会话错误SessionError
-32051客户端签名验证失败ClientSignatureError(继承自 ValidationError
-32029请求限流(目标/联邦维度)RateLimitError
-32429请求限流(Gateway 入口背压,排队超时)RateLimitError
-32600 / -32601 / -32602JSON-RPC 参数错误ValidationError
-32602 且消息包含 group.index etag conflictgroup.index CAS 冲突应重新 getGroupIndex、合并、签名后重试
-32602 且消息包含 group.index 签名/schema/hash/etag 错误group.index 校验失败检查 signer、canonical JSONL、body_hashetagsignature
-32040 ~ -32044E2EE 群组错误E2EEError 子类
4090身份冲突IdentityConflictError
-32050证书已吊销CertificateRevokedError
-33001群组不存在GroupNotFoundError
-33002 / -33003群组状态错误GroupStateError
-33004 ~ -33009其他群组错误GroupError 子类

重试策略

python
from aun_core import AUNError, RateLimitError, AuthError

async def send_with_retry(client, params, max_retries=3):
    for i in range(max_retries):
        try:
            return await client.call("message.send", params)
        except RateLimitError:
            await asyncio.sleep(2 ** i)
        except AuthError:
            raise
        except AUNError as e:
            if not e.retryable or i == max_retries - 1:
                raise
            await asyncio.sleep(0.5)

常见错误场景

未加载身份

python
client = AUNClient()
await client.connect()  # StateError: no_identity

修复方式:

python
loaded = store.load(MY_AID)
client.load_identity(loaded["data"]["aid"])
await client.connect({"auto_reconnect": True})

传入字符串 AID 构造客户端

python
AUNClient("alice.agentid.pub")  # TypeError / ValidationError

AID 必须来自 AIDStore.load()

python
me = store.load("alice.agentid.pub")["data"]["aid"]
client = AUNClient(me)

身份冲突

python
registered = await store.register("alice.agentid.pub")
if not registered["ok"] and registered["error"]["code"] == "IDENTITY_CONFLICT":
    print("AID 已被其他密钥注册,换名或恢复原私钥")

不要通过删除本地 AIDs/ 目录解决冲突;私钥丢失后无法证明原 AID 所有权。

连接状态错误

python
await client.call("message.send", params)  # 非 ready 状态会抛 ConnectionError / StateError

发送前检查:

python
if not client.can_send:
    await client.connect({"auto_reconnect": True})

refresh_token 失效

当自动刷新命中 missing refresh_tokeninvalid_or_expired_refresh_token、刷新链耗尽或服务端返回 relogin_required=true 时,SDK 会清理本地 access_token / refresh_token / kite_token,发布 token.refresh_exhausted 事件,并在后续重连时重新走完整登录链路。应用层可监听该事件提示用户重新授权;不要继续复用旧 token。

E2EE 解密失败

P2P 或群消息解密失败通常由 prekey 不匹配、AAD 篡改、密文损坏或群 epoch 不一致引起。SDK 会发布 message.undecryptable / group.message_undecryptable 事件,应用可记录并继续处理其他消息。

group.index CAS 冲突

多个 owner/admin 并发修改公告、规则或入群要求时,服务端通过 expected_index_etag 做 CAS。冲突时错误消息包含 group.index etag conflict

处理方式:

python
try:
    await client.group.update_group_index({
        "group_id": group_aid,
        "settings": {"announcement.content": "new text"},
    })
except Exception as exc:
    if "etag conflict" in str(exc):
        latest = await client.group.get_group_index({"group_id": group_aid})
        # 在 latest["entries"] 上合并本地修改,然后重新 update_group_index
        raise
    raise

通常优先使用 SDK 的 updateGroupIndex facade;它会按 max_attempts 自动重读当前 index 并重试。超过重试次数仍冲突时,把冲突交给应用层做合并策略。

AUN Protocol Documentation