Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should anyhow::Error::chain return dyn Error + Send + Sync #327

Open
ten3roberts opened this issue Nov 28, 2023 · 2 comments
Open

Should anyhow::Error::chain return dyn Error + Send + Sync #327

ten3roberts opened this issue Nov 28, 2023 · 2 comments

Comments

@ten3roberts
Copy link

ten3roberts commented Nov 28, 2023

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?

@ten3roberts
Copy link
Author

The same goes for the root_cause API, which with the lack of Send + Sync makes an anyhow conversion non-bijective

@dtolnay
Copy link
Owner

dtolnay commented Dec 26, 2023

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 _ }),
    })
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants