Skip to main content

ResultExt

Trait ResultExt 

Source
pub trait ResultExt<V, E> {
Show 24 methods // Required methods fn into_report( self, ) -> Result<V, Report<<E as IntoReport<SendSync>>::Context, <E as IntoReport<SendSync>>::Ownership>> where E: IntoReport<SendSync>; fn context<C>(self, context: C) -> Result<V, Report<C>> where E: IntoReportCollection<SendSync>, C: Send + Sync + Display + Debug; fn context_with<C, F>(self, context: F) -> Result<V, Report<C>> where E: IntoReportCollection<SendSync>, F: FnOnce() -> C, C: Send + Sync + Display + Debug; fn context_custom<H, C>(self, context: C) -> Result<V, Report<C>> where E: IntoReportCollection<SendSync>, C: Send + Sync, H: ContextHandler<C>; fn context_custom_with<H, C, F>(self, context: F) -> Result<V, Report<C>> where E: IntoReportCollection<SendSync>, F: FnOnce() -> C, C: Send + Sync, H: ContextHandler<C>; fn context_to<C>(self) -> Result<V, Report<C>> where E: IntoReport<SendSync>, C: ReportConversion<<E as IntoReport<SendSync>>::Context, <E as IntoReport<SendSync>>::Ownership, SendSync>; fn context_transform<C, F>(self, f: F) -> Result<V, Report<C>> where E: IntoReport<SendSync, Ownership = Mutable>, <E as IntoReport<SendSync>>::Context: Sized, F: FnOnce(<E as IntoReport<SendSync>>::Context) -> C, C: Send + Sync + Display + Debug; fn context_transform_nested<C, F>(self, f: F) -> Result<V, Report<C>> where E: IntoReport<SendSync, Ownership = Mutable>, <E as IntoReport<SendSync>>::Context: Sized, F: FnOnce(<E as IntoReport<SendSync>>::Context) -> C, C: Send + Sync + Display + Debug; fn attach<A>( self, attachment: A, ) -> Result<V, Report<<E as IntoReport<SendSync>>::Context>> where E: IntoReport<SendSync, Ownership = Mutable>, A: 'static + Send + Sync + Display + Debug; fn attach_with<A, F>( self, attachment: F, ) -> Result<V, Report<<E as IntoReport<SendSync>>::Context>> where E: IntoReport<SendSync, Ownership = Mutable>, F: FnOnce() -> A, A: 'static + Send + Sync + Display + Debug; fn attach_custom<H, A>( self, attachment: A, ) -> Result<V, Report<<E as IntoReport<SendSync>>::Context>> where E: IntoReport<SendSync, Ownership = Mutable>, A: 'static + Send + Sync, H: AttachmentHandler<A>; fn attach_custom_with<H, A, F>( self, attachment: F, ) -> Result<V, Report<<E as IntoReport<SendSync>>::Context>> where E: IntoReport<SendSync, Ownership = Mutable>, F: FnOnce() -> A, A: 'static + Send + Sync, H: AttachmentHandler<A>; fn local_into_report( self, ) -> Result<V, Report<<E as IntoReport<Local>>::Context, <E as IntoReport<Local>>::Ownership, Local>> where E: IntoReport<Local>; fn local_context<C>( self, context: C, ) -> Result<V, Report<C, Mutable, Local>> where E: IntoReportCollection<Local>, C: Display + Debug; fn local_context_with<C, F>( self, context: F, ) -> Result<V, Report<C, Mutable, Local>> where E: IntoReportCollection<Local>, F: FnOnce() -> C, C: Display + Debug; fn local_context_custom<H, C>( self, context: C, ) -> Result<V, Report<C, Mutable, Local>> where E: IntoReportCollection<Local>, H: ContextHandler<C>; fn local_context_custom_with<H, C, F>( self, context: F, ) -> Result<V, Report<C, Mutable, Local>> where E: IntoReportCollection<Local>, F: FnOnce() -> C, H: ContextHandler<C>; fn local_context_to<C>(self) -> Result<V, Report<C, Mutable, Local>> where E: IntoReport<Local>, C: ReportConversion<<E as IntoReport<Local>>::Context, <E as IntoReport<Local>>::Ownership, Local>; fn local_context_transform<C, F>( self, f: F, ) -> Result<V, Report<C, Mutable, Local>> where E: IntoReport<Local, Ownership = Mutable>, <E as IntoReport<Local>>::Context: Sized, F: FnOnce(<E as IntoReport<Local>>::Context) -> C, C: Display + Debug; fn local_context_transform_nested<C, F>( self, f: F, ) -> Result<V, Report<C, Mutable, Local>> where E: IntoReport<Local, Ownership = Mutable>, <E as IntoReport<Local>>::Context: Sized, F: FnOnce(<E as IntoReport<Local>>::Context) -> C, C: Display + Debug; fn local_attach<A>( self, attachment: A, ) -> Result<V, Report<<E as IntoReport<Local>>::Context, Mutable, Local>> where E: IntoReport<Local, Ownership = Mutable>, A: 'static + Display + Debug; fn local_attach_with<A, F>( self, attachment: F, ) -> Result<V, Report<<E as IntoReport<Local>>::Context, Mutable, Local>> where E: IntoReport<Local, Ownership = Mutable>, F: FnOnce() -> A, A: 'static + Display + Debug; fn local_attach_custom<H, A>( self, attachment: A, ) -> Result<V, Report<<E as IntoReport<Local>>::Context, Mutable, Local>> where A: 'static, E: IntoReport<Local, Ownership = Mutable>, H: AttachmentHandler<A>; fn local_attach_custom_with<H, A, F>( self, attachment: F, ) -> Result<V, Report<<E as IntoReport<Local>>::Context, Mutable, Local>> where A: 'static, E: IntoReport<Local, Ownership = Mutable>, F: FnOnce() -> A, H: AttachmentHandler<A>;
}
Expand description

Extension trait for Result that provides error handling and reporting functionality.

This trait adds methods to Result types that allow you to convert errors into Reports with additional context and attachments. It provides both thread-safe (Send + Sync) and local-only variants of each method.

The methods in this trait fall into several categories:

Each method has a local_* variant for working with types that are not Send + Sync.

Required Methods§

Source

fn into_report( self, ) -> Result<V, Report<<E as IntoReport<SendSync>>::Context, <E as IntoReport<SendSync>>::Ownership>>
where E: IntoReport<SendSync>,

Converts the error into a Report.

If the result is Ok, returns the value unchanged. If the result is Err, converts the error into a Report.

See also local_into_report for a non-thread-safe version that works with types that are not Send + Sync.

§Examples
use std::io;

use rootcause::prelude::*;

fn read_config() -> Result<String, io::Error> {
    std::fs::read_to_string("config.toml")
}

let result: Result<String, Report<io::Error>> = read_config().into_report();
Source

fn context<C>(self, context: C) -> Result<V, Report<C>>

Converts the error into a new Report using the provided context. The current error is set as a child of the new Report.

If the result is Ok, returns the value unchanged. If the result is Err, converts the error into a report collection and adds the provided context. The context becomes the primary error message, with the original error becoming part of the error chain.

This method also works when the original error is a ReportCollection, in which case all errors in that collection are set as children of the new Report.

See also local_context for a non-thread-safe version that works with types that are not Send + Sync.

§Examples
use std::io;

use rootcause::prelude::*;

fn fetch_data(path: &str) -> Result<Vec<u8>, io::Error> {
    std::fs::read(path)
}

let result: Result<Vec<u8>, Report<&str>> =
    fetch_data("user_data.bz2").context("Failed to fetch user data");
Source

fn context_with<C, F>(self, context: F) -> Result<V, Report<C>>
where E: IntoReportCollection<SendSync>, F: FnOnce() -> C, C: Send + Sync + Display + Debug,

Converts the error into a new Report using context generated by the provided closure. The current error is set as a child of the new Report.

This is similar to context, but the context is computed lazily using a closure. This can be useful when computing the context is expensive, as the closure will only be called if an error actually occurs.

This method also works when the original error is a ReportCollection, in which case all errors in that collection are set as children of the new Report.

See also local_context_with for a non-thread-safe version that works with types that are not Send + Sync.

§Examples
use std::io;

use rootcause::prelude::*;

fn get_timestamp() -> String {
    "12:34:56".to_string()
}

let result: Result<Vec<u8>, Report<String>> =
    std::fs::read("user_data.bz2").context_with(|| format!("Failed at {}", get_timestamp()));
Source

fn context_custom<H, C>(self, context: C) -> Result<V, Report<C>>

Converts the error into a new Report using the provided context. The current error is set as a child of the new Report.

This is similar to context, but uses a custom ContextHandler to control how the context is formatted and displayed.

This method also works when the original error is a ReportCollection, in which case all errors in that collection are set as children of the new Report.

See also local_context_custom for a non-thread-safe version that works with types that are not Send + Sync.

§Examples
use std::io;

use rootcause::prelude::*;

#[derive(Debug)]
enum ErrorContext {
    DeserializationError,
    IoError,
}

let result: Result<Vec<u8>, Report<ErrorContext>> =
    std::fs::read("user_data.bz2").context_custom::<handlers::Debug, _>(ErrorContext::IoError);
Source

fn context_custom_with<H, C, F>(self, context: F) -> Result<V, Report<C>>
where E: IntoReportCollection<SendSync>, F: FnOnce() -> C, C: Send + Sync, H: ContextHandler<C>,

Converts the error into a new Report using context generated by the provided closure. The current error is set as a child of the new Report.

Combines the lazy evaluation of context_with with the custom handler capabilities of context_custom.

This method also works when the original error is a ReportCollection, in which case all errors in that collection are set as children of the new Report.

See also local_context_custom_with for a non-thread-safe version that works with types that are not Send + Sync.

§Examples
use std::io;

use rootcause::prelude::*;

#[derive(Debug)]
struct ErrorContext {
    timestamp: String,
    operation: String,
}

fn expensive_computation() -> ErrorContext {
    ErrorContext {
        timestamp: "12:34:56".to_string(),
        operation: "file_read".to_string(),
    }
}

let result: Result<Vec<u8>, Report<ErrorContext>> =
    std::fs::read("user_data.bz2")
        .context_custom_with::<handlers::Debug, _, _>(expensive_computation);
Source

fn context_to<C>(self) -> Result<V, Report<C>>

Converts the error to a different context type using ReportConversion.

If Err, converts the error into a Report and transforms it using the ReportConversion implementation. Implement ReportConversion once to define conversions, then use context_to() at call sites. The target type C is typically inferred from the return type.

See also: local_context_to (non-Send + Sync version), examples/thiserror_interop.rs (integration patterns).

§Examples
// After implementing ReportConversion, use at call sites:
let result: Result<i32, Report<AppError>> = "abc".parse::<i32>().context_to();
Source

fn context_transform<C, F>(self, f: F) -> Result<V, Report<C>>
where E: IntoReport<SendSync, Ownership = Mutable>, <E as IntoReport<SendSync>>::Context: Sized, F: FnOnce(<E as IntoReport<SendSync>>::Context) -> C, C: Send + Sync + Display + Debug,

Transforms the error’s context using a closure, preserving the report structure.

If Err, converts to a Report and applies the closure to transform the context in-place, keeping all children and attachments. Bypasses the report creation hook. See Report::context_transform for details.

See also: local_context_transform (non-Send + Sync version), context_transform_nested (creates new parent), examples/context_methods.rs (comparison guide).

§Examples
#[derive(Debug)]
enum AppError {
    Io(io::Error)
}

let result: Result<String, Report<AppError>> =
    std::fs::read_to_string("config.toml").context_transform(AppError::Io);
Source

fn context_transform_nested<C, F>(self, f: F) -> Result<V, Report<C>>
where E: IntoReport<SendSync, Ownership = Mutable>, <E as IntoReport<SendSync>>::Context: Sized, F: FnOnce(<E as IntoReport<SendSync>>::Context) -> C, C: Send + Sync + Display + Debug,

Transforms the error’s context while nesting the original report as a child.

If Err, converts to a Report, preformats it, and wraps it as a child under the new context. Report creation hooks run again, capturing fresh hook data. See Report::context_transform_nested for details.

See also: local_context_transform_nested (non-Send + Sync version), context_transform (preserves structure), examples/context_methods.rs (comparison guide).

§Examples
#[derive(Debug)]
enum AppError {
    Io(io::Error)
}

let result: Result<String, Report<AppError>> =
    std::fs::read_to_string("config.toml").context_transform_nested(AppError::Io);
Source

fn attach<A>( self, attachment: A, ) -> Result<V, Report<<E as IntoReport<SendSync>>::Context>>
where E: IntoReport<SendSync, Ownership = Mutable>, A: 'static + Send + Sync + Display + Debug,

Converts the error into a Report and adds the provided attachment to the Report.

If the result is Ok, returns the value unchanged. If the result is Err, converts the error into a Report and attaches the provided data as an attachment. Attachments provide additional context without changing the primary error message.

See also local_attach for a non-thread-safe version that works with types that are not Send + Sync.

§Examples
use std::io;

use rootcause::prelude::*;

let result: Result<Vec<u8>, Report<io::Error>> =
    std::fs::read("user_data.bz2").attach("while reading user_data.bz2");
Source

fn attach_with<A, F>( self, attachment: F, ) -> Result<V, Report<<E as IntoReport<SendSync>>::Context>>
where E: IntoReport<SendSync, Ownership = Mutable>, F: FnOnce() -> A, A: 'static + Send + Sync + Display + Debug,

Converts the error into a Report and adds an attachment generated by the provided closure to the Report.

This is similar to attach, but the attachment is computed lazily using a closure. This can be useful when computing the attachment is expensive, as the closure will only be called if an error actually occurs.

See also local_attach_with for a non-thread-safe version that works with types that are not Send + Sync.

§Examples
use std::io;

use rootcause::prelude::*;

fn get_debug_info() -> String {
    "complex computation result".to_string()
}

let result: Result<Vec<u8>, Report<io::Error>> =
    std::fs::read("user_data.bz2").attach_with(|| format!("debug info: {}", get_debug_info()));
Source

fn attach_custom<H, A>( self, attachment: A, ) -> Result<V, Report<<E as IntoReport<SendSync>>::Context>>
where E: IntoReport<SendSync, Ownership = Mutable>, A: 'static + Send + Sync, H: AttachmentHandler<A>,

Converts the error into a Report and adds the provided attachment to the Report.

This is similar to attach, but uses a custom AttachmentHandler to control how the attachment is formatted and displayed.

See also local_attach_custom for a non-thread-safe version that works with types that are not Send + Sync.

§Examples
use std::io;

use rootcause::prelude::*;

#[derive(Debug)]
struct RequestMetadata {
    request_id: u64,
    user_id: u64,
}

let metadata = RequestMetadata {
    request_id: 12345,
    user_id: 67890,
};

let result: Result<Vec<u8>, Report<io::Error>> =
    std::fs::read("user_data.bz2").attach_custom::<handlers::Debug, _>(metadata);
Source

fn attach_custom_with<H, A, F>( self, attachment: F, ) -> Result<V, Report<<E as IntoReport<SendSync>>::Context>>
where E: IntoReport<SendSync, Ownership = Mutable>, F: FnOnce() -> A, A: 'static + Send + Sync, H: AttachmentHandler<A>,

Converts the error into a Report and adds an attachment generated by the provided closure to the Report.

Combines the lazy evaluation of attach_with with the custom handler capabilities of attach_custom.

See also local_attach_custom_with for a non-thread-safe version that works with types that are not Send + Sync.

§Examples
use std::io;

use rootcause::prelude::*;

#[derive(Debug)]
struct RequestMetadata {
    request_id: u64,
    timestamp: String,
}

fn expensive_computation() -> RequestMetadata {
    RequestMetadata {
        request_id: 12345,
        timestamp: "12:34:56".to_string(),
    }
}

let result: Result<Vec<u8>, Report<io::Error>> = std::fs::read("user_data.bz2")
    .attach_custom_with::<handlers::Debug, _, _>(expensive_computation);
Source

fn local_into_report( self, ) -> Result<V, Report<<E as IntoReport<Local>>::Context, <E as IntoReport<Local>>::Ownership, Local>>
where E: IntoReport<Local>,

Converts the error into a local (non-thread-safe) Report.

If the result is Ok, returns the value unchanged. If the result is Err, converts the error into a Report that can contain types that are not Send + Sync.

This allows you to use rootcause with error types that contain thread-local data like Rc or other !Send types.

See also into_report for a thread-safe version that returns a Report that can be sent across thread boundaries.

§Examples
use std::{fmt, rc::Rc};

use rootcause::prelude::*;

// This error is neither Send nor Sync
#[derive(Debug)]
struct MyError(Rc<String>);

impl fmt::Display for MyError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl std::error::Error for MyError {}

fn some_function() -> Result<String, MyError> {
    Err(MyError(Rc::new("error".to_string())))
}

let result: Result<String, Report<MyError, _, markers::Local>> =
    some_function().local_into_report();
Source

fn local_context<C>(self, context: C) -> Result<V, Report<C, Mutable, Local>>

Converts the error into a new local (non-thread-safe) Report using the provided context. The current error is set as a child of the new Report.

If the result is Ok, returns the value unchanged. If the result is Err, converts the error into a report collection and adds the provided context. The context becomes the primary error message, with the original error becoming part of the error chain.

This method also works when the original error is a ReportCollection, in which case all errors in that collection are set as children of the new Report.

See also context for a thread-safe version that returns a Report that can be sent across thread boundaries.

§Examples
use std::{io, rc::Rc};

use rootcause::prelude::*;

fn fetch_data(path: &str) -> Result<Vec<u8>, io::Error> {
    std::fs::read(path)
}

let result: Result<Vec<u8>, Report<Rc<&str>, _, markers::Local>> =
    fetch_data("user_data.bz2").local_context(Rc::from("Failed to fetch user data"));
Source

fn local_context_with<C, F>( self, context: F, ) -> Result<V, Report<C, Mutable, Local>>
where E: IntoReportCollection<Local>, F: FnOnce() -> C, C: Display + Debug,

Converts the error into a new local (non-thread-safe) Report using context generated by the provided closure. The current error is set as a child of the new Report.

This is similar to local_context, but the context is computed lazily using a closure. This can be useful when computing the context is expensive, as the closure will only be called if an error actually occurs.

This method also works when the original error is a ReportCollection, in which case all errors in that collection are set as children of the new Report.

See also context_with for a thread-safe version that returns a Report that can be sent across thread boundaries.

§Examples
use std::{io, rc::Rc};

use rootcause::prelude::*;

#[derive(Debug)]
struct ContextData {
    timestamp: Rc<String>,
    operation: String,
}

impl std::fmt::Display for ContextData {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}: {}", self.timestamp, self.operation)
    }
}

fn expensive_computation() -> ContextData {
    // Expensive computation that builds context data
    ContextData {
        timestamp: Rc::new("12:34:56".to_string()),
        operation: "file_read".to_string(),
    }
}

let result: Result<Vec<u8>, Report<ContextData, _, markers::Local>> =
    std::fs::read("user_data.bz2").local_context_with(expensive_computation);
Source

fn local_context_custom<H, C>( self, context: C, ) -> Result<V, Report<C, Mutable, Local>>

Converts the error into a new local (non-thread-safe) Report using the provided context. The current error is set as a child of the new Report.

This is similar to local_context, but uses a custom ContextHandler to control how the context is formatted and displayed.

This method also works when the original error is a ReportCollection, in which case all errors in that collection are set as children of the new Report.

See also context_custom for a thread-safe version that returns a Report that can be sent across thread boundaries.

§Examples
use std::{io, rc::Rc};

use rootcause::prelude::*;

#[derive(Debug)]
enum ErrorContext {
    DeserializationError,
    IoError,
}

let result: Result<Vec<u8>, Report<Rc<ErrorContext>, _, markers::Local>> =
    std::fs::read("user_data.bz2")
        .local_context_custom::<handlers::Debug, _>(Rc::new(ErrorContext::IoError));
Source

fn local_context_custom_with<H, C, F>( self, context: F, ) -> Result<V, Report<C, Mutable, Local>>
where E: IntoReportCollection<Local>, F: FnOnce() -> C, H: ContextHandler<C>,

Converts the error into a new local (non-thread-safe) Report using context generated by the provided closure. The current error is set as a child of the new Report.

Combines the lazy evaluation of local_context_with with the custom handler capabilities of local_context_custom.

This method also works when the original error is a ReportCollection, in which case all errors in that collection are set as children of the new Report.

See also context_custom_with for a thread-safe version that returns a Report that can be sent across thread boundaries.

§Examples
use std::{io, rc::Rc};

use rootcause::prelude::*;

#[derive(Debug)]
struct ErrorContext {
    timestamp: Rc<String>,
    operation: String,
}

fn expensive_computation() -> Rc<ErrorContext> {
    Rc::new(ErrorContext {
        timestamp: Rc::new("12:34:56".to_string()),
        operation: "file_read".to_string(),
    })
}

let result: Result<Vec<u8>, Report<Rc<ErrorContext>, _, markers::Local>> =
    std::fs::read("user_data.bz2")
        .local_context_custom_with::<handlers::Debug, _, _>(expensive_computation);
Source

fn local_context_to<C>(self) -> Result<V, Report<C, Mutable, Local>>

Non-Send + Sync version of context_to.

Converts the error to a different context type using ReportConversion, producing a local (non-thread-safe) Report. Allows working with context types that are not Send + Sync.

§Examples
// After implementing ReportConversion:
let result: Result<i32, Report<LocalError, _, markers::Local>> = "abc".parse::<i32>().local_context_to();
Source

fn local_context_transform<C, F>( self, f: F, ) -> Result<V, Report<C, Mutable, Local>>
where E: IntoReport<Local, Ownership = Mutable>, <E as IntoReport<Local>>::Context: Sized, F: FnOnce(<E as IntoReport<Local>>::Context) -> C, C: Display + Debug,

Non-Send + Sync version of context_transform.

Transforms the error’s context using a closure, preserving the report structure. Produces a local (non-thread-safe) Report.

§Examples
use std::rc::Rc;
use rootcause::prelude::*;

#[derive(Debug)]
enum AppError {
    Io(Rc<io::Error>)  // Rc is not Send + Sync
}

let result: Result<String, Report<AppError, _, markers::Local>> =
    std::fs::read_to_string("config.toml").local_context_transform(|e| AppError::Io(Rc::new(e)));
Source

fn local_context_transform_nested<C, F>( self, f: F, ) -> Result<V, Report<C, Mutable, Local>>
where E: IntoReport<Local, Ownership = Mutable>, <E as IntoReport<Local>>::Context: Sized, F: FnOnce(<E as IntoReport<Local>>::Context) -> C, C: Display + Debug,

Non-Send + Sync version of context_transform_nested.

Transforms the error’s context while nesting the original report as a child. Produces a local (non-thread-safe) Report. Report creation hooks run again.

§Examples
use std::rc::Rc;
use rootcause::prelude::*;

#[derive(Debug)]
enum AppError {
    Io(Rc<io::Error>)  // Rc is not Send + Sync
}

let result: Result<String, Report<AppError, _, markers::Local>> =
    std::fs::read_to_string("config.toml").local_context_transform_nested(|e| AppError::Io(Rc::new(e)));
Source

fn local_attach<A>( self, attachment: A, ) -> Result<V, Report<<E as IntoReport<Local>>::Context, Mutable, Local>>
where E: IntoReport<Local, Ownership = Mutable>, A: 'static + Display + Debug,

Converts the error into a local (non-thread-safe) Report and adds the provided attachment to the Report.

If the result is Ok, returns the value unchanged. If the result is Err, converts the error into a Report and attaches the provided data as an attachment. Attachments provide additional context without changing the primary error message.

See also attach for a thread-safe version that returns a Report that can be sent across thread boundaries.

§Examples
use std::{io, rc::Rc};

use rootcause::prelude::*;

// In this case it might make more sense to use `local_attach_with`, but
// you can assume that the attachment is pre-computed.
let attachment: Rc<&str> = Rc::from("input: invalid_data");
let result: Result<Vec<u8>, Report<io::Error, _, markers::Local>> =
    std::fs::read("user_data.bz2").local_attach(attachment);
Source

fn local_attach_with<A, F>( self, attachment: F, ) -> Result<V, Report<<E as IntoReport<Local>>::Context, Mutable, Local>>
where E: IntoReport<Local, Ownership = Mutable>, F: FnOnce() -> A, A: 'static + Display + Debug,

Converts the error into a local (non-thread-safe) Report and adds an attachment generated by the provided closure to the Report.

This is similar to local_attach, but the attachment is computed lazily using a closure. This can be useful when computing the attachment is expensive, as the closure will only be called if an error actually occurs.

See also attach_with for a thread-safe version that returns a Report that can be sent across thread boundaries.

§Examples
use std::{io, rc::Rc};

use rootcause::prelude::*;

fn get_debug_info() -> String {
    "complex computation result".to_string()
}

let result: Result<Vec<u8>, Report<io::Error, _, markers::Local>> =
    std::fs::read("user_data.bz2")
        .local_attach_with(|| Rc::new(format!("debug info: {}", get_debug_info())));
Source

fn local_attach_custom<H, A>( self, attachment: A, ) -> Result<V, Report<<E as IntoReport<Local>>::Context, Mutable, Local>>
where A: 'static, E: IntoReport<Local, Ownership = Mutable>, H: AttachmentHandler<A>,

Converts the error into a local (non-thread-safe) Report and adds the provided attachment to the Report.

This is similar to local_attach, but uses a custom AttachmentHandler to control how the attachment is formatted and displayed.

See also attach_custom for a thread-safe version that returns a Report that can be sent across thread boundaries.

§Examples
use std::{io, rc::Rc};

use rootcause::prelude::*;

#[derive(Debug)]
struct RequestMetadata {
    request_id: Rc<u64>,
    user_id: u64,
}

// In this case it might make more sense to use `local_attach_custom_with`, but
// you can assume that the attachment is pre-computed.
let metadata: Rc<RequestMetadata> = Rc::new(RequestMetadata {
    request_id: Rc::new(12345),
    user_id: 67890,
});

let result: Result<Vec<u8>, Report<io::Error, _, markers::Local>> =
    std::fs::read("user_data.bz2").local_attach_custom::<handlers::Debug, _>(metadata);
Source

fn local_attach_custom_with<H, A, F>( self, attachment: F, ) -> Result<V, Report<<E as IntoReport<Local>>::Context, Mutable, Local>>
where A: 'static, E: IntoReport<Local, Ownership = Mutable>, F: FnOnce() -> A, H: AttachmentHandler<A>,

Converts the error into a local (non-thread-safe) Report and adds an attachment generated by the provided closure to the Report.

Combines the lazy evaluation of local_attach_with with the custom handler capabilities of local_attach_custom.

See also attach_custom_with for a thread-safe version that returns a Report that can be sent across thread boundaries.

§Examples
use std::{io, rc::Rc};

use rootcause::prelude::*;

#[derive(Debug)]
struct RequestMetadata {
    request_id: Rc<u64>,
    timestamp: String,
}

fn expensive_computation() -> RequestMetadata {
    RequestMetadata {
        request_id: Rc::new(12345),
        timestamp: "12:34:56".to_string(),
    }
}

let result: Result<Vec<u8>, Report<io::Error, _, markers::Local>> =
    std::fs::read("user_data.bz2")
        .local_attach_custom_with::<handlers::Debug, _, _>(|| Rc::new(expensive_computation()));

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl<V, E> ResultExt<V, E> for Result<V, E>

Source§

fn into_report( self, ) -> Result<V, Report<<E as IntoReport<SendSync>>::Context, <E as IntoReport<SendSync>>::Ownership>>
where E: IntoReport<SendSync>,

Source§

fn context<C>(self, context: C) -> Result<V, Report<C>>

Source§

fn context_with<C, F>(self, context: F) -> Result<V, Report<C>>
where E: IntoReportCollection<SendSync>, F: FnOnce() -> C, C: Send + Sync + Display + Debug,

Source§

fn context_custom<H, C>(self, context: C) -> Result<V, Report<C>>

Source§

fn context_custom_with<H, C, F>(self, context: F) -> Result<V, Report<C>>
where E: IntoReportCollection<SendSync>, F: FnOnce() -> C, C: Send + Sync, H: ContextHandler<C>,

Source§

fn context_to<C>(self) -> Result<V, Report<C>>

Source§

fn context_transform<C, F>(self, f: F) -> Result<V, Report<C>>
where E: IntoReport<SendSync, Ownership = Mutable>, <E as IntoReport<SendSync>>::Context: Sized, F: FnOnce(<E as IntoReport<SendSync>>::Context) -> C, C: Send + Sync + Display + Debug,

Source§

fn context_transform_nested<C, F>(self, f: F) -> Result<V, Report<C>>
where E: IntoReport<SendSync, Ownership = Mutable>, <E as IntoReport<SendSync>>::Context: Sized, F: FnOnce(<E as IntoReport<SendSync>>::Context) -> C, C: Send + Sync + Display + Debug,

Source§

fn attach<A>( self, attachment: A, ) -> Result<V, Report<<E as IntoReport<SendSync>>::Context>>
where E: IntoReport<SendSync, Ownership = Mutable>, A: 'static + Send + Sync + Display + Debug,

Source§

fn attach_with<A, F>( self, attachment: F, ) -> Result<V, Report<<E as IntoReport<SendSync>>::Context>>
where E: IntoReport<SendSync, Ownership = Mutable>, F: FnOnce() -> A, A: 'static + Send + Sync + Display + Debug,

Source§

fn attach_custom<H, A>( self, attachment: A, ) -> Result<V, Report<<E as IntoReport<SendSync>>::Context>>
where E: IntoReport<SendSync, Ownership = Mutable>, A: 'static + Send + Sync, H: AttachmentHandler<A>,

Source§

fn attach_custom_with<H, A, F>( self, attachment: F, ) -> Result<V, Report<<E as IntoReport<SendSync>>::Context>>
where E: IntoReport<SendSync, Ownership = Mutable>, F: FnOnce() -> A, A: 'static + Send + Sync, H: AttachmentHandler<A>,

Source§

fn local_into_report( self, ) -> Result<V, Report<<E as IntoReport<Local>>::Context, <E as IntoReport<Local>>::Ownership, Local>>
where E: IntoReport<Local>,

Source§

fn local_context<C>(self, context: C) -> Result<V, Report<C, Mutable, Local>>

Source§

fn local_context_with<C, F>( self, context: F, ) -> Result<V, Report<C, Mutable, Local>>
where E: IntoReportCollection<Local>, F: FnOnce() -> C, C: Display + Debug,

Source§

fn local_context_custom<H, C>( self, context: C, ) -> Result<V, Report<C, Mutable, Local>>

Source§

fn local_context_custom_with<H, C, F>( self, context: F, ) -> Result<V, Report<C, Mutable, Local>>
where E: IntoReportCollection<Local>, F: FnOnce() -> C, H: ContextHandler<C>,

Source§

fn local_context_to<C>(self) -> Result<V, Report<C, Mutable, Local>>

Source§

fn local_context_transform<C, F>( self, f: F, ) -> Result<V, Report<C, Mutable, Local>>
where E: IntoReport<Local, Ownership = Mutable>, <E as IntoReport<Local>>::Context: Sized, F: FnOnce(<E as IntoReport<Local>>::Context) -> C, C: Display + Debug,

Source§

fn local_context_transform_nested<C, F>( self, f: F, ) -> Result<V, Report<C, Mutable, Local>>
where E: IntoReport<Local, Ownership = Mutable>, <E as IntoReport<Local>>::Context: Sized, F: FnOnce(<E as IntoReport<Local>>::Context) -> C, C: Display + Debug,

Source§

fn local_attach<A>( self, attachment: A, ) -> Result<V, Report<<E as IntoReport<Local>>::Context, Mutable, Local>>
where E: IntoReport<Local, Ownership = Mutable>, A: 'static + Display + Debug,

Source§

fn local_attach_with<A, F>( self, attachment: F, ) -> Result<V, Report<<E as IntoReport<Local>>::Context, Mutable, Local>>
where E: IntoReport<Local, Ownership = Mutable>, F: FnOnce() -> A, A: 'static + Display + Debug,

Source§

fn local_attach_custom<H, A>( self, attachment: A, ) -> Result<V, Report<<E as IntoReport<Local>>::Context, Mutable, Local>>
where A: 'static, E: IntoReport<Local, Ownership = Mutable>, H: AttachmentHandler<A>,

Source§

fn local_attach_custom_with<H, A, F>( self, attachment: F, ) -> Result<V, Report<<E as IntoReport<Local>>::Context, Mutable, Local>>
where A: 'static, E: IntoReport<Local, Ownership = Mutable>, F: FnOnce() -> A, H: AttachmentHandler<A>,

Implementors§