pub type Location = &'static Location<'static>;Expand description
The source code location where the error was reported.
To use it, add a field of type Location to your error and
register it as implicitly generated data. When
constructing the error, you do not need to provide the location:
#[derive(Debug, Snafu)]
struct NeighborhoodError {
#[snafu(implicit)]
loc: snafu::Location,
}
fn check_next_door() -> Result<(), NeighborhoodError> {
ensure!(everything_quiet(), NeighborhoodSnafu);
Ok(())
}§Limitations
Implicitly generated data, including Location, is generated when
the wrapping error value is constructed:
// The first we know about the error is on this line:
let e = fallible_code();
// but the location will correspond to this line:
e.context(InterestingSnafu)?;If you have disabled the context selector, the
Location will correspond to where the From implementation is
invoked. This is usually part of the ? operator:
// The first we know about the error is on this line:
let e = fallible_code();
// but the location will correspond to this line:
e?;Inspecting the code at the generated Location will usually
quickly lead back to the original error, but it’s recommended to
create the wrapping error as close to the original error location
to reduce confusion.
§Asynchronous code
When using SNAFU’s
TryFutureExt
or
TryStreamExt
extension traits, the automatically captured location will
correspond to where the future or stream was polled, not where
it was created. Additionally, many Future or Stream
combinators do not forward the caller’s location to their
closures, causing the recorded location to be inside of the future
combinator’s library.
There are two workarounds:
- Avoid combinators and use the non-async
ResultExt - Construct the location explicitly, such as by the
location!macro
// Non-ideal: will report where `wrapped_error_future` is `.await`ed.
let wrapped_error_future = error_future.context(ImplicitLocationSnafu);
// Better: will report the location of `.context`.
let wrapped_error_future = async { error_future.await.context(ImplicitLocationSnafu) };
// Better: Will report the location of `location!`
let wrapped_error_future = error_future.with_context(|_| ExplicitLocationSnafu {
location: location!(),
});
#[derive(Debug, Snafu)]
struct ImplicitLocationError {
source: AnotherError,
#[snafu(implicit)]
location: snafu::Location,
}
#[derive(Debug, Snafu)]
struct ExplicitLocationError {
source: AnotherError,
location: snafu::Location,
}