SDKC++ SDK

诊断与错误

设备状态、自动连接恢复与错误处理。

当前版本 · 1.4.0

诊断与错误

先读:Debug 日志(先开日志再复现问题) · 读完你能:读懂设备状态、自动连接恢复与错误类型

按症状定位问题见 常见问题;这一章给出读取设备状态与处理错误的工具。

设备状态与诊断

device.status() 返回 ReadChannel<GloveStatus>。常用字段包括 connected、stale、 timestamp、last_error、reconnect_count 和 fields。需要持续监控时订阅 status;只关心当前值时使用 latest()。完整字段见 GloveStatus。

自动连接恢复

自动恢复只用于已经成功启动、随后意外断开的 source;首次运行连接失败由 start() 同步返回。恢复期间只有受影响的 source 进入 connected=false、stale=true,并通过 last_error 报告原因,其他 source 继续运行。身份确认后的恢复会重新变为 connected=true,清除 last_error 并增加 reconnect_count。恢复前已经 start() 并重新收到数据时,stale=false;尚未 start() 的 source 恢复连接后仍保持 stale=true,直到开始接收当前数据。

流程图渲染中

断连期间发送 haptics 或其他设备命令会立即以 not-connected 错误失败,不排队,也不重放。当前震动设置会清空;恢复后必须由应用重新设置。显式调用 stop() 或 close() 会取消恢复。对同一已确认设备,已经就绪且仍有效的 Retargeting 输出可以在恢复后继续使用,不会仅因重连而重新标定。

sdk.health() 返回整个 SDK 的聚合状态,glove.health() 返回全部已配置手套的状态。判断运行期是否健康,应在停止请求前读取并记录 running health:

const auto running_health = glove.health();
std::cout << "running health ok=" << running_health.ok << '\n';

Health 包括:

  • ok:当前是否健康。
  • warning_count 与 error_count:累计诊断计数。
  • devices:每个 source 的连接、陈旧与错误状态。
  • last_error:最近的错误摘要。
  • runtime_overrun:是否观察到运行任务超时。
  • topic_callback_error:表示 SDK 数据处理过程中记录的 callback 错误。subscribe() 回调抛出的异常不会逃出回调边界,也不会设置 topic_callback_error;如需观测,请在回调内部自行记录或处理。

主动停止并等待运行循环结束后,可以在关闭前再读取 stopped lifecycle health,用于确认设备的 connected/stale 生命周期状态。停止遥测后设备会进入 stale=true,所以即使 warning_count=0、error_count=0,聚合值也可能是 ok=false。这是预期的停止生命周期状态,不表示运行失败,也不会改变共享 Health.ok 的含义。完整顺序见 foreground_runtime.cpp 和 background_runtime.cpp。完整返回字段见 Health。

错误处理

按失败场景捕获最具体的异常类型,并优先使用异常提供的结构化信息:

异常典型含义
InvalidArgumentError配置、frame、haptics 或调用参数无效
ClosedHandleErrorSDK 或 Glove 已关闭
StaleUpdateErrorupdate result 已消费或失效
LifecycleError生命周期顺序或运行模式不允许当前操作
UnavailableFeatureError当前设备、平台或交付不支持该能力
CommandRejectedError控制命令被拒绝
GloveControlError设备控制命令失败:未连接、设备忙、超时等,原因见 kind(GloveControlErrorKind)
InternalErrorSDK 无法继续该操作
PanicError未预期的运行失败

设备或 target 选择另有 NotFoundSelectionError 与 AmbiguousSelectionError,两者携带结构化 selector 和 candidate 信息。异步等待取消使用标准 std::system_error(std::errc::operation_canceled)。

按具体恢复策略捕获异常,再以 QnBotError 作为最后的 SDK 错误边界:

try {
    auto device = glove.device("primary");
} catch (const qnbot::NotFoundSelectionError& error) {
    for (const auto& candidate : error.candidates()) {
        std::cerr << candidate << '\n';
    }
} catch (const qnbot::QnBotError& error) {
    std::cerr << error.what() << '\n';
}