18

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` 
1
  • When asking for why some code does not compile, you should include code that can be actually given to the compiler to show the error. Preferably with a link to a copy in play.rust-lang.org. In this case the detail that hides the devil is in those ... after run_server(args)?. That is, you didn't post enough details to answer why the closure returns (). Commented Jun 11, 2019 at 7:40

1 Answer 1

15

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

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.