I think current rough consensus is anyhow/thiserr depending on if you're writing an application or library. I haven't actually used them myself, though. You don't have to keep up with the cool new libraries.
Manual impls may be tedious to write, but they change rarely after they've been written, enough that the con of adding one more dependency that may go away tomorrow outweighs the con of writing them manually.
This lets me write code like this:
#[derive(From, Debug)]
pub enum SomeSpecificError {
Io(io::Error),
SomeAppLevelErrorCondition,
}
fn do_something() -> Result<(), SomeSpecificError> {
do_some_io()?;
// ...
}
Previously I would have written: fn do_something() -> Result<(), SomeSpecificError> {
do_some_io().map_err(SomeSpecificError::Io)?;
}
I find this approach results in clear code that continues to compile and work just fine over time, even as everything changes around it.[0] https://jeltef.github.io/derive_more/derive_more/from.html#e...
In general, I feel `?`'s automatic `From::from` conversion leads to bad errors, because the programmer is incentivized to have type-specific context via implementing `From<>` rather than operation-specific context, even though operation-specific context leads to better error messages. Consider the difference between:
failed to initialize library
caused by: an I/O error occurred
caused by: no such file or directory (2)
and failed to initialize library
caused by: could not read config file at /path/to/config.toml
caused by: no such file or directory (2)
Edit: I should add that it is possible to use `From<>` when the type-specific contexts and operation-specific contexts form a bijection. In the above example, if there were dedicated `struct ReadConfigError(std::path::PathBuf, std::io::Error)` and `struct ConnectToServerError(std::net::SocketAddr, std::io::Error)` types, then having the higher-level `Error` impl `From<ReadConfigError>` and `From<ConnectToServerError>` would be perfectly fine. Of course, that would just shift the issue down to those types since they would not be able to impl `From<std::io::Error>`. Also, in my experience, libraries rarely bother having such individual operation-specific error types anyway.Might suit some people.
https://boats.gitlab.io/blog/post/failure-to-fehler/
From the article:
> The crate I would recommend to anyone who likes failure’s API is anyhow, which basically provides the failure::Error type (a fancy trait object), but based on the std Error trait instead of on.