|
|
|
|
|
by Expurple
356 days ago
|
|
> multiple error variants that reference the same source error type which I always had issues with in `thiserror`. Huh? #[derive(Debug, thiserror::Error)]
enum CustomError {
#[error("failed to open a: {0}")]
A(std::io::Error),
#[error("failed to open b: {0}")]
B(std::io::Error),
}
fn main() -> Result<(), CustomError> {
std::fs::read_to_string("a").map_err(CustomError::A)?;
std::fs::read_to_string("b").map_err(CustomError::B)?;
Ok(())
}
If I understand correctly, the main feature of snafu is "merely" reducing the boilerplace when adding context: low_level_result.context(ErrorWithContextSnafu { context })?;
// vs
low_level_result.map_err(|err| ErrorWithContext { err, context })?;
But to me, the win seems to small to justify the added complexity. |
|
- You don't need to move the inner error yourself.
- You don't need to use a closure, which saves a few characters. This is even true in cases where you have a reference and want to store the owned value in the error:
- You can choose to capture certain values implicitly, such as a source file location, a backtrace, or your own custom data (the current time, a global-ish request ID, etc.)----
As an aside:
It is now discouraged to include the text of the inner error in the `Display` of the wrapping error. Including it leads to duplicated data when printing out chains of errors in a nicer / structured manner. SNAFU has a few types that work to undo this duplication, but it's better to avoid it in the first place.