# AUN SDK Python - 错误处理

---

## 错误类层级

```
AUNError
├── ConnectionError        # 网络连接失败
├── TimeoutError           # 操作超时
├── AuthError              # 认证失败（code: 4001/4010）
├── PermissionError        # 权限不足（code: 4030）
├── ValidationError        # 参数校验失败（code: 4000/-32600/-32602）
├── NotFoundError          # 资源不存在（code: 4040）
├── RateLimitError         # 请求限流（code: 4290），retryable=True
├── StateError             # 非法状态操作
├── SerializationError     # JSON 序列化失败
├── SessionError           # 会话错误（code: -32010/-32013）
├── GroupError
│   ├── GroupNotFoundError  # code: -33001
│   └── GroupStateError     # code: -33002/-33003
└── E2EEError
    ├── E2EEDecryptFailedError              # P2P 消息解密失败
    ├── E2EEGroupSecretMissingError         # code: -32040，缺少群密钥
    ├── E2EEGroupEpochMismatchError         # code: -32041，epoch 不匹配
    ├── E2EEGroupCommitmentInvalidError     # code: -32042，成员承诺验证失败
    ├── E2EEGroupNotMemberError             # code: -32043，请求者非群成员
    └── E2EEGroupDecryptFailedError         # code: -32044，群消息解密失败
```

## 错误属性

```python
from aun_core import AUNError

try:
    await client.call("method.name", {...})
except AUNError as e:
    e.code       # int，错误码
    e.data       # Any，附加数据
    e.retryable  # bool，是否可重试
    e.trace_id   # str | None，追踪 ID
```

## 错误码速查

| 范围 | 含义 | 对应异常 |
|------|------|----------|
| 4000 | 参数校验失败 | `ValidationError` |
| 4001 / 4010 | 认证失败 | `AuthError` |
| 4030 | 权限不足 | `PermissionError` |
| 4040 | 资源不存在 | `NotFoundError` |
| 4290 | 请求限流 | `RateLimitError` |
| -32600 / -32602 | JSON-RPC 参数错误 | `ValidationError` |
| -32010 / -32013 | 会话错误 | `SessionError` |
| -33001 | 群组不存在 | `GroupNotFoundError` |
| -33002 / -33003 | 群组状态异常 | `GroupStateError` |
| -32040 | 缺少群密钥 | `E2EEGroupSecretMissingError` |
| -32041 | 群 epoch 不匹配 | `E2EEGroupEpochMismatchError` |
| -32042 | 成员承诺验证失败 | `E2EEGroupCommitmentInvalidError` |
| -32043 | 密钥请求者非群成员 | `E2EEGroupNotMemberError` |
| -32044 | 群消息解密失败 | `E2EEGroupDecryptFailedError` |

## 重试策略

```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.call("message.send", {...})  # → AuthError

# ✅ 正确：先认证再操作
auth = await client.auth.authenticate({"aid": MY_AID})
await client.connect(auth, {})
await client.call("message.send", {...})
```

### E2EE 解密失败

```python
# E2EEDecryptFailedError — prekey 不匹配、AAD 篡改、密文损坏
# SDK 自动处理：解密失败的消息返回原始密文，不中断其他消息
```

### 群组 E2EE 错误

```python
# E2EEGroupSecretMissingError — 发送加密群消息时本地无群密钥
# 常见于建群后 create_epoch 尚未完成、或通过邀请码入群后尚未恢复密钥
# SDK 会抛出此异常，调用方可捕获后等待密钥恢复完成再重试
# SDK 自动编排：建群后自动 create_epoch；缺密钥时自动发起恢复请求

# E2EEGroupDecryptFailedError — 群消息解密失败（密钥不匹配或密文损坏）
# 协议层定义的错误语义，当前 Python SDK 的部分路径表现为返回 None、拒绝状态或跳过自动解密，不一定抛出对应异常

# E2EEGroupEpochMismatchError — 收到的密钥分发 epoch 低于当前 epoch
# 协议层定义的错误语义，当前 Python SDK 的部分路径表现为返回 None、拒绝状态或跳过自动解密，不一定抛出对应异常

# E2EEGroupCommitmentInvalidError — 收到的密钥分发中成员承诺校验失败
# 协议层定义的错误语义，当前 Python SDK 的部分路径表现为返回 None、拒绝状态或跳过自动解密，不一定抛出对应异常
# 可能原因：中间人篡改、成员列表不一致

# E2EEGroupNotMemberError — 密钥恢复请求被拒，请求者不在群成员列表中
# 协议层定义的错误语义，当前 Python SDK 的部分路径表现为返回 None、拒绝状态或跳过自动解密，不一定抛出对应异常
```

### 连接状态错误

```python
# ❌ 错误：断连后直接调用
await client.call("message.send", {...})  # → StateError

# ✅ 正确：重新认证并启用自动重连
auth = await client.auth.authenticate({"aid": MY_AID})
await client.connect(auth, {
    "auto_reconnect": True,
})
```
