How to return error propagation in thead spawn and async

Hello,

How can I return and propagate error from a thread task or from async func (executed with block_on) ?

Example for threads :

use std::thread;

enum Error {
    Foo,
}

fn make_thread() {
    thread::spawn(|| {bar()?});
}

fn bar() -> Result<(), Error> {
    Ok(())
}

fn main() {
    make_thread();
}
error[E0277]: the `?` operator can only be used in a closure that returns `Result` or `Option` (or another type that implements `FromResidual`)
   --> src/main.rs:8:28
    |
8   |     thread::spawn(|| {bar()?});
    |                   ---------^-
    |                   |        |
    |                   |        cannot use the `?` operator in a closure that returns `()`
    |                   this function should return `Result` or `Option` to accept `?`

And same question for task::block_on(async { ....

I don't find how to do that :frowning:
Thanks !

You can do something like:

fn make_thread() -> Result<(), Error> {
    let p = thread::spawn(|| bar());
    p.join().unwrap()
}

That said, you probably shouldn't unwrap but check on that as well, and make a new error.

You can fix your thread::spawn example by replacing || { bar()? } with

|| {
    bar()?;
    Ok(())
}

so that the return type of the closure is Result<(), Error>. The reason your original code doesn't work is that the type of the expression bar()? is/should be (), so the return type of the closure is inferred to be (), which is incompatible with using ?.

Hello,

Thanks for your help !

For :frowning:

use std::thread;

enum Error {
    Foo,
}

fn make_thread() {
    thread::spawn(|| {bar()?; Ok(())});
}

fn bar() -> Result<(), Error> {
    Ok(())
}

fn main() {
    make_thread();
}

I got :

error[E0282]: type annotations needed
 --> src/main.rs:8:31
  |
8 |     thread::spawn(|| {bar()?; Ok(())});
  |                               ^^ cannot infer type for type parameter `E` declared on the enum `Result`

Ah, yeah, that's annoying. The quickest fix is to add a turbofish somewhere, either Ok::<_, Error>(()) or thread::spawn::<_, Result<_, Error>>. I think type inference falls over in this case because ? has an (unfortunate imo) implicit conversion with From::from built in, it's the same issue that causes inference problems for try blocks.

Hello ! JoinHandle return the thread result ? Thats cool !

Intersting ! I look on that.

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.