It's a common trick to annotate your functions with returning Result<X, Box<dyn Error>>
to allow them to return any error at all. However, you can't return this from a thread without the error itself implementing Send
. For example this code:
use rayon::prelude::*; // 1.5.1
use std::error::Error;
fn main(){
["1", "2", "three"]
.into_par_iter()
.try_for_each(|i| -> Result<usize, Box<dyn Error>> {
let inner = i.parse::<usize>()?;
Ok(inner)
}
);
}
Gives this error:
error[E0277]: `dyn std::error::Error` cannot be sent between threads safely
On the other hand, if you try to specify that the error must implement Send
, the ?
operator no longer works:
use rayon::prelude::*; // 1.5.1
use std::error::Error;
fn main(){
["1", "2", "three"]
.into_par_iter()
.try_for_each(|i| -> Result<usize, Box<dyn Error + Send>> {
let inner = i.parse::<usize>()?;
Ok(inner)
}
);
}
error[E0277]: `?` couldn't convert the error to `Box<dyn std::error::Error + Send>`
How can I continue to use the Box<dyn Error>
shortcut, but only for errors that can be sent, allowing it to work across threads?