错误类型
BotRS 中所有可能失败的调用都返回 Result<T, BotError>。BotError 是一个 enum,覆盖传输、协议、本地校验等失败场景,并通过 Sdk 变体兜底承载所有 QQ 侧返回的错误码。
rust
pub type Result<T> = std::result::Result<T, BotError>;BotError 由 thiserror::Error 派生,自动实现了 std::error::Error,并提供可读的 Display 字符串。
变体一览
| 变体 | 来源 |
|---|---|
Sdk(SdkError) | QQ 定义的错误码,可能附带响应体。 |
Http(reqwest::Error) | HTTP 客户端的传输 / TLS / DNS / 超时错误。 |
WebSocket(Box<tungstenite::Error>) | 网关 WebSocket 失败。 |
Json(serde_json::Error) | 载荷反序列化失败。 |
Url(url::ParseError) | 构造请求 URL 失败。 |
Api { code: u32, message: String } | 非 2xx 响应及解析后的响应体。 |
AuthenticationFailed(String) | 令牌签名或 Authorization 头被拒绝。 |
NotFound(String) | 404 / 资源不存在。 |
MethodNotAllowed(String) | 405。 |
Forbidden(String) | 403 / 权限不足。 |
RateLimit { retry_after: u64 } | 429,附带解析后的 Retry-After(秒)。 |
SequenceNumber(String) | 低层映射保留的 sequence/order 错误。 |
Server(String) | 5xx 响应,并携带解析后的平台诊断信息。 |
Auth(String) | 更高层级的鉴权 / 会话问题。 |
Connection(String) | 网关生命周期或心跳失败。 |
Config(String) | 请求开始之前的配置错误。 |
InvalidData(String) | 本地校验(例如非法的权限串)失败。 |
Timeout | 内部各阶段抛出的网络超时。 |
Gateway(String) | 其他不属于上述任一变体的网关协议错误。 |
Session(String) | 网关会话状态机错误。 |
Internal(String) | 框架自身的不变量被破坏(视为 bug)。 |
Io(std::io::Error) | 本地 I/O,例如文件上传。 |
Sdk 包装的是框架内部的错误码载体 SdkError,其方法包括 code()、message()、trace_id()。框架将 QQ 定义的所有数值错误码(例如 9999、CODE_CONN_CLOSE_CANT_RESUME、CODE_CONN_CLOSE_CANT_IDENTIFY 等)经 Sdk 派发。
构造辅助
BotError 上提供了一组短构造器,便于在框架内部构建错误:
BotError::invalid_data(msg)—— 快捷构造InvalidData。BotError::auth(msg)/BotError::config(msg)/BotError::internal(msg)—— 各自对应的变体。
模式匹配
rust
use botrs::BotError;
match api.get_bot_info().await {
Ok(bot) => println!("{}", bot.username),
Err(BotError::Http(e)) if e.is_timeout() => warn!("timed out"),
Err(BotError::RateLimit { retry_after }) => {
tokio::time::sleep(Duration::from_secs(retry_after)).await;
}
Err(BotError::Forbidden(msg)) => warn!("permission denied: {msg}"),
Err(BotError::Api { code, message }) => warn!("qq api error {code}: {message}"),
Err(other) => return Err(other),
}需要根据协议错误码做分支时:
rust
if let BotError::Sdk(ref err) = e {
match err.code() {
CODE_CONN_CLOSE_CANT_RESUME => /* 抛弃会话,重新 identify */,
CODE_CONN_CLOSE_CANT_IDENTIFY => /* 停止 identify,等待状态变化 */,
_ => {}
}
}这些常量从 botrs::error 暴露,例如 botrs::error::CODE_CONN_CLOSE_CANT_RESUME。
自动转换
BotError 为常用的内部错误类型实现了 From(reqwest::Error、serde_json::Error、url::ParseError、std::io::Error),因此 async fn -> Result<...> 中可以直接使用 ?。