pub trait ResultExt<T, E>: Sized {
fn context<C, E2>(self, context: C) -> Result<T, E2>
where
C: IntoError<E2, Source = E>,
E2: Error + ErrorCompat;
fn with_context<F, C, E2>(self, context: F) -> Result<T, E2>
where
F: FnOnce(&mut E) -> C,
C: IntoError<E2, Source = E>,
E2: Error + ErrorCompat;
fn whatever_context<S, E2>(self, context: S) -> Result<T, E2>
where
S: Into<String>,
E2: FromString,
E: Into<E2::Source>;
fn with_whatever_context<F, S, E2>(self, context: F) -> Result<T, E2>
where
F: FnOnce(&mut E) -> S,
S: Into<String>,
E2: FromString,
E: Into<E2::Source>;
}
Expand description
Additions to Result
.
Required Methods§
sourcefn context<C, E2>(self, context: C) -> Result<T, E2>where
C: IntoError<E2, Source = E>,
E2: Error + ErrorCompat,
fn context<C, E2>(self, context: C) -> Result<T, E2>where
C: IntoError<E2, Source = E>,
E2: Error + ErrorCompat,
Extend a Result
’s error with additional context-sensitive information.
use snafu::prelude::*;
#[derive(Debug, Snafu)]
enum Error {
Authenticating {
user_name: String,
user_id: i32,
source: ApiError,
},
}
fn example() -> Result<(), Error> {
another_function().context(AuthenticatingSnafu {
user_name: "admin",
user_id: 42,
})?;
Ok(())
}
fn another_function() -> Result<i32, ApiError> {
/* ... */
}
Note that the context selector will call
Into::into
on each field, so the types
are not required to exactly match.
sourcefn with_context<F, C, E2>(self, context: F) -> Result<T, E2>where
F: FnOnce(&mut E) -> C,
C: IntoError<E2, Source = E>,
E2: Error + ErrorCompat,
fn with_context<F, C, E2>(self, context: F) -> Result<T, E2>where
F: FnOnce(&mut E) -> C,
C: IntoError<E2, Source = E>,
E2: Error + ErrorCompat,
Extend a Result
’s error with lazily-generated context-sensitive information.
use snafu::prelude::*;
#[derive(Debug, Snafu)]
enum Error {
Authenticating {
user_name: String,
user_id: i32,
source: ApiError,
},
}
fn example() -> Result<(), Error> {
another_function().with_context(|_| AuthenticatingSnafu {
user_name: "admin".to_string(),
user_id: 42,
})?;
Ok(())
}
fn another_function() -> Result<i32, ApiError> {
/* ... */
}
Note that this may not be needed in many cases because the context
selector will call Into::into
on each
field.
sourcefn whatever_context<S, E2>(self, context: S) -> Result<T, E2>where
S: Into<String>,
E2: FromString,
E: Into<E2::Source>,
fn whatever_context<S, E2>(self, context: S) -> Result<T, E2>where
S: Into<String>,
E2: FromString,
E: Into<E2::Source>,
Extend a Result
’s error with information from a string.
The target error type must implement FromString
by using
the
#[snafu(whatever)]
attribute. The premade Whatever
type is also available.
In many cases, you will want to use
with_whatever_context
instead
as it gives you access to the error and is only called in case
of error. This method is best suited for when you have a
string literal.
use snafu::{prelude::*, Whatever};
fn example() -> Result<(), Whatever> {
std::fs::read_to_string("/this/does/not/exist")
.whatever_context("couldn't open the file")?;
Ok(())
}
let err = example().unwrap_err();
assert_eq!("couldn't open the file", err.to_string());
sourcefn with_whatever_context<F, S, E2>(self, context: F) -> Result<T, E2>where
F: FnOnce(&mut E) -> S,
S: Into<String>,
E2: FromString,
E: Into<E2::Source>,
fn with_whatever_context<F, S, E2>(self, context: F) -> Result<T, E2>where
F: FnOnce(&mut E) -> S,
S: Into<String>,
E2: FromString,
E: Into<E2::Source>,
Extend a Result
’s error with information from a
lazily-generated string.
The target error type must implement FromString
by using
the
#[snafu(whatever)]
attribute. The premade Whatever
type is also available.
use snafu::{prelude::*, Whatever};
fn example() -> Result<(), Whatever> {
let filename = "/this/does/not/exist";
std::fs::read_to_string(filename)
.with_whatever_context(|_| format!("couldn't open the file {}", filename))?;
Ok(())
}
let err = example().unwrap_err();
assert_eq!(
"couldn't open the file /this/does/not/exist",
err.to_string(),
);
The closure is not called when the Result
is Ok
:
use snafu::{prelude::*, Whatever};
let value: std::io::Result<i32> = Ok(42);
let result = value.with_whatever_context::<_, String, Whatever>(|_| {
panic!("This block will not be evaluated");
});
assert!(result.is_ok());