anyhow
anyhow copied to clipboard
Should `anyhow::Error::chain` return `dyn Error + Send + Sync`
anyhow::Error only supports wrapping Send + Sync errors, but the API for chainreturns non-send and non-sync errors.
I suspect this is to mimic the source stdlib API, if so, would it be advisable to introduce a chain_send_sync method?
- https://docs.rs/anyhow/latest/anyhow/struct.Error.html#method.chain
- https://docs.rs/anyhow/latest/anyhow/struct.Chain.html
The same goes for the root_cause API, which with the lack of Send + Sync makes an anyhow conversion non-bijective
What would be the expected behavior if the causes or root cause are not Send + Sync?
// [dependencies]
// anyhow = "1"
// threadbound = "0.1"
use std::fmt::{self, Display};
use threadbound::ThreadBound;
#[derive(Debug)]
struct OuterError {
inner: ThreadBound<InnerError>,
}
impl std::error::Error for OuterError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
let inner = self.inner.get_ref()?;
Some(inner)
}
}
impl Display for OuterError {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("...")
}
}
#[derive(Copy, Clone, Debug)]
struct InnerError {
p: *const (), // not sync
}
impl std::error::Error for InnerError {}
impl Display for InnerError {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("...")
}
}
fn main() {
let err = f().unwrap_err();
for e in err.chain() {
println!("{}", e);
}
}
fn f() -> anyhow::Result<()> {
g()?;
Ok(())
}
fn g() -> Result<(), OuterError> {
Err(OuterError {
inner: ThreadBound::new(InnerError { p: 0 as _ }),
})
}