deviceplug / btleplug

Rust Cross-Platform Host-Side Bluetooth LE Access Library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

btleplug::Error doesn't work with anyhow

ohazi opened this issue · comments

If I want to use btleplug in an application that uses anyhow for errors, I might attempt to do the following:

use anyhow::Context;

async fn get_manager() -> anyhow::Result<Manager> {
    Manager::new()
        .await
        .context("Failed to create a BLE manager")?
}

and expect things to just work.

Instead, I'm told that I can't call .context because of some unsatisfied trait bounds:

error[E0599]: the method `context` exists for enum `Result<btleplug::platform::Manager, btleplug::Error>`, but its trait bounds were not satisfied
   --> src/main.rs:13:10
    |
13  |         .context("Failed to create a BLE manager")?
    |          ^^^^^^^ method cannot be called on `Result<btleplug::platform::Manager, btleplug::Error>` due to unsatisfied trait bounds
    | 
   ::: /home/ohazi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:241:1
    |
241 | pub enum Result<T, E> {
    | --------------------- doesn't satisfy `_: anyhow::Context<btleplug::platform::Manager, btleplug::Error>`
    | 
   ::: /home/ohazi/.cargo/registry/src/github.com-1ecc6299db9ec823/btleplug-0.8.0/src/lib.rs:112:1
    |
112 | pub enum Error {
    | --------------
    | |
    | doesn't satisfy `btleplug::Error: Send`
    | doesn't satisfy `btleplug::Error: Sync`
    | doesn't satisfy `btleplug::Error: anyhow::context::ext::StdError`
    |
    = note: the following trait bounds were not satisfied:
            `btleplug::Error: anyhow::context::ext::StdError`
            which is required by `Result<btleplug::platform::Manager, btleplug::Error>: anyhow::Context<btleplug::platform::Manager, btleplug::Error>`
            `btleplug::Error: Send`
            which is required by `Result<btleplug::platform::Manager, btleplug::Error>: anyhow::Context<btleplug::platform::Manager, btleplug::Error>`
            `btleplug::Error: Sync`
            which is required by `Result<btleplug::platform::Manager, btleplug::Error>: anyhow::Context<btleplug::platform::Manager, btleplug::Error>`

This is because the last Other(Box<dyn std::error::Error>) variant of btleplug::Error doesn't require the boxed Error to be Send or Sync.

Since btleplug is an async library, it would be awfully convenient to be able to toss errors across thread boundaries freely. Would making this a requirement break anything? Right now, the only thing Other is used for seems to be boxed strings and a boxed bluez_async::BluetoothError, both of which are Send + Sync, so I think this should work.

Fixed in dev by #179.