|
|
|
|
|
by Arnavion
2258 days ago
|
|
Unless you want all I/O errors to be indistinguishable to your callers, you should use more specific variants than a single `Io(std::io::Error)`, like `ReadConfig(std::path::PathBuf, std::io::Error)` and `ConnectToServer(std::net::SocketAddr, std::io::Error)`. And if you do so, the `From` impl becomes untenable and you have to fall back to `.map_err(...)?`. 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. |
|
https://docs.rs/snafu/0.6.6/snafu/