How to fix: future cannot be sent between threads safely

This is the simplest example where I can reproduce my issue. I think I understand why it's happening. But how do I fix it?

fn main() {
    tokio::spawn(async move {
        if let Err(error) = do_something().await {
            do_something_else().await;
        }
    });
}

async fn do_something() -> Result<(), Box<dyn std::error::Error>> {
    async {}.await;
    Ok(())
}

async fn do_something_else() -> Result<(), Box<dyn std::error::Error>> {
    async {}.await;
    Ok(())
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error: future cannot be sent between threads safely
   --> src/main.rs:2:18
    |
2   |       tokio::spawn(async move {
    |  __________________^
3   | |         if let Err(error) = do_something().await {
4   | |             do_something_else().await;
5   | |         }
6   | |     });
    | |_____^ future created by async block is not `Send`
    |
    = help: the trait `Send` is not implemented for `dyn std::error::Error`
note: future is not `Send` as this value is used across an await
   --> src/main.rs:4:33
    |
3   |         if let Err(error) = do_something().await {
    |                    ----- has type `Box<dyn std::error::Error>` which is not `Send`
4   |             do_something_else().await;
    |                                 ^^^^^ await occurs here, with `error` maybe used later
5   |         }
    |         - `error` is later dropped here
note: required by a bound in `tokio::spawn`
   --> /playground/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.29.1/src/task/spawn.rs:166:21
    |
164 |     pub fn spawn<T>(future: T) -> JoinHandle<T::Output>
    |            ----- required by a bound in this function
165 |     where
166 |         T: Future + Send + 'static,
    |                     ^^^^ required by this bound in `spawn`

error: could not compile `playground` (bin "playground") due to previous error

Use Box<dyn std::error::Error + Send> (or perhaps even + Send + Sync).

4 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.