4 ms·
> snafu vs thiserror/anyhow I'd like to provide a fair comparison [1] in the documentation, but I don't know thiserror / anyhow well enough to feel like I'd gi
by shepmaster 5y ago
> snafu vs thiserror/anyhow
I'd like to provide a fair comparison [1] in the documentation, but I don't know thiserror / anyhow well enough to feel like I'd give them the credit they are due.
That said, to my knowledge, thiserror doesn't allow you to take an `io::Error` and sort it into two different enum variants (like the `Reading` and `Opening` variants in my grandparent example). To me, those are vastly different error states that just both happen to have the same error type. You can extend the metaphor with any larger error type from a crate (e.g. `reqwest::Error`).
Anyhow requires using a trait object (and potentially downcasting) and I prefer avoiding those when possible.
> seemed the popularly recommended way
Absolutely. The author of those crates is a giant in the Rust community [2] (they are also the author of serde, syn, and quote, for example!). If those crates suit your situations, then by all means — use them. I'd much rather the Rust community have better error types and messages by whatever means available. Even using `String` via `Box<dyn Error>` is better than nothing.
> you won't get autocompletion
You should, at least if you use rust-analyzer. I use it via emacs and have these settings enabled, but I think they were going to be the default:
(lsp-rust-analyzer-cargo-load-out-dirs-from-check t)
(lsp-rust-analyzer-proc-macro-enable t)
[1]: https://docs.rs/snafu/0.7.0-beta.1/snafu/guide/comparison/index.html https://docs.rs/snafu/0.7.0-beta.1/snafu/guide/comparison/in...
[2]: https://crates.io/users/dtolnay https://crates.io/users/dtolnay
- rileyphone 5y agoThanks for the emacs tip! I've been dealing with that for a minute and here is the solution in hn comments, what serendipity.
- nagisa 5y ago`thiserror` definitely does allow it, e.g. #[derive(thiserror::Error, Debug)] pub enum Error { #[error("Cannot open `{1}`")] OpenFile(#[source] std::io::Error, PathBuf) #[error("Cannot read file contents")] ReadFileContents(#[source] std::io::Error) #[error("Cannot parse the configuration file")] ParseConfig(#[source] serde::Error) } fn open_config(path: &Path) -> Result<Config, Error> { let mut file = File::open(path).map_err(|e| Error::OpenFile(e, path.to_owned()))?; let mut data = Vec::with_capacity(1024); file.read_to_end(&mut data).map_err(Error::ReadFileContents)?; parse_config(&data).map_err(Error::ParseConfig) } EDIT: adjusted to add an example of adding path to the error message.
- shepmaster 5y agoI should have worded myself better, apologies. With that example, since you use `Result::map_err` and specify the specific variant, you aren't really using anything from thiserror at the site of the `?`, correct? Most usages I have seen, people use `#[from]`, which would end up having conflicting implementations. Is there a reason you didn't use `#[from]` for `ParseConfig`?
- nagisa 5y agoAh, I see. In short, I consider `From::from` implementations for errors to be an anti-pattern. It is super easy to become lax about adding context with these implementations in place. Especially as code is modified in the future. I describe the approach that I use for errors in a detail in an article (https://kazlauskas.me/entries/errors.html https://kazlauskas.me/entries/errors.html) that has already been linked elsewhere in the thread. It is, as far as I can tell, pretty much equivalent to what `snafu` makes users to do.
- OJFord 5y agoThanks! > To my knowledge, thiserror doesn't allow you to take an `io::Error` and sort it into two different enum variants (like the `Reading` and `Opening` variants in my grandparent example) Indeed that does look nice, I don't know for sure either, I'm only very basically using it. (Which is where it's been a bit of a pain at times - to be honest for where I've been using it so far I just wanted a dead simple 'I really don't care just return the basic error message in some way that compiles'.) > The author of those crates is a giant in the Rust community [dtolnay] For what it's worth, I haven't conducted any sort of objective metric-based comparison obviously, but I recognise both of your usernames equally as giants. ;) > You should [get autocompletion on *Snafu], at least if you use rust-analyzer Oh, clever. "[rust-analyzer] is a part of a larger rls-2.0 effort to create excellent IDE support for Rust." I'll have to check, but I'm pretty sure I'm using 'rls-1.0' (in vim).