I want to propagate an error from a function called inside a closure inside a call to thread::spawn
.
I've tried using a JoinHandle
to capture the result of thread::spawn
, but I get various errors doing that.
fn start_server(args) -> Result<(), Box<dyn std::error::Error>> {
...
thread::spawn(move || {
// I want to do this (put a ? after run_server)
run_server(args)?;
...
}
...
});
fn run_server(args) -> Result<(), std::io::Error> {
...
}
I get this message
| run_server(args)?;
| ^^^^^^^^^^^^^^^^^ cannot use the `?` operator in a function that returns `()`
|
= help: the trait `std::ops::Try` is not implemented for `()`
= note: required by `std::ops::Try::from_error`
I want to propagate an error from a function called inside a closure inside a call to thread::spawn
Since threads are running in parallel, throwing the error up from the thread scope is not making sense. Better approach will be error handling in the thread itself.
So generally you should not propagate the error to the upper level above the thread.
However you can throw your error
that you get in your parallel threads
after you joined
them to your main thread
. This way it will be pretty much like error propagation in synchronous.
Here is how you can manage it:
fn start_server() -> Result<(), Box<std::error::Error>> {
let x = std::thread::spawn(move || -> Result<(), std::io::Error> {
run_server()?;
Ok(())
});
x.join().unwrap()?; // Now you can throw your error up because you joined your thread.
// ...
Ok(())
}
fn run_server() -> Result<(), std::io::Error> {
Err(std::io::Error::new(std::io::ErrorKind::Other, "hello"))
}
fn main() {
let x = start_server();
println!("{:?}", x);
}
Playground
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With