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

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.

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.

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());

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());

Implementations on Foreign Types

Implementors