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

Add Clone support #7

Closed
krojew opened this issue Oct 8, 2019 · 4 comments
Closed

Add Clone support #7

krojew opened this issue Oct 8, 2019 · 4 comments

Comments

@krojew
Copy link

krojew commented Oct 8, 2019

Currently anyhow::Error is not Clone, which makes the crate hard (or even impossible) to use with some mock crates in tests, e.g. mock-it.

@dtolnay
Copy link
Owner

dtolnay commented Oct 8, 2019

In order to provide a Clone impl we would need to do either of:

  • require that you can only construct anyhow::Error from errors that are Clone, which would make it incompatible with many error types in the wild like io::Error and serde_json::Error; or
  • reference-count the internal error.

The first one seems bad to me and the second one makes it impossible to downcast by value which also seems bad (fwiw failure came to the same conclusion in rust-lang-deprecated/failure#148).

Is there a way for you to work around this by using Rc<Error> or Arc<Error> in the tests?

@krojew
Copy link
Author

krojew commented Oct 8, 2019

My first though was about using Arc, but that introduced a ton of changes which were not really needed from the api standpoint. Unfortunately, the work required outweighed the benefit of using anyhow. And there's also the possibility of passing error across 3rd party crates which don't wrap results in anything.

@dtolnay
Copy link
Owner

dtolnay commented Oct 8, 2019

That's too bad. I am sorry to hear that it didn't work out for your use case!

@dtolnay dtolnay closed this as completed Oct 8, 2019
@oconnor663
Copy link

oconnor663 commented Oct 16, 2019

I was writing a question about this, but I think I answered it for myself. Here it is, in case anyone else has it.

Q: How can I use anyhow::Result inside of a global static once_cell::sync::Lazy<anyhow::Result<T>>, given that the error is not Clone? How can a caller report the error if it can't be cloned out of the Result?

A: Use a once_cell::sync::OnceCell<T> instead and initialize it with get_or_try_init. Probably wrap all of that inside a function returning anyhow::Result<&T>, with the OnceCell as a local static inside the function body. That gives the error value to the caller who tried to initialize it. Subsequent callers can try again, and they'll get their own errors. (This assumes that either it's ok for subsequent callers to try again, or that you'll quit the first time you encounter an error.)

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

No branches or pull requests

3 participants