pub struct AsyncErrorPipeline<Fut> { /* private fields */ }Expand description
Async error pipeline for chainable error handling.
This is the async counterpart to ErrorPipeline,
providing fluent, chainable error context accumulation for async operations.
§Examples
§Basic Usage
use error_rail::prelude_async::*;
#[derive(Debug)]
struct Data;
#[derive(Debug)]
struct ApiError;
async fn fetch_data(_id: u64) -> Result<Data, ApiError> {
Err(ApiError)
}
async fn example(id: u64) -> BoxedResult<Data, ApiError> {
AsyncErrorPipeline::new(fetch_data(id))
.with_context("fetching data")
.finish_boxed()
.await
}§With Multiple Contexts
use error_rail::prelude_async::*;
#[derive(Debug)]
struct Order;
#[derive(Debug)]
struct OrderError;
async fn load_order(_order_id: u64) -> Result<Order, OrderError> {
Err(OrderError)
}
async fn process_order(order_id: u64) -> BoxedResult<Order, OrderError> {
AsyncErrorPipeline::new(load_order(order_id))
.with_context(group!(
message("loading order"),
metadata("order_id", format!("{}", order_id))
))
.finish_boxed()
.await
}Implementations§
Source§impl<Fut> AsyncErrorPipeline<Fut>
impl<Fut> AsyncErrorPipeline<Fut>
Sourcepub fn finish(self) -> Fut
pub fn finish(self) -> Fut
Completes the pipeline and returns the inner future.
This method consumes the pipeline and returns a future that
produces the original Result<T, E>.
§Examples
use error_rail::async_ext::AsyncErrorPipeline;
async fn example() -> Result<i32, &'static str> {
AsyncErrorPipeline::new(async { Ok(42) })
.finish()
.await
}Source§impl<Fut, T, E> AsyncErrorPipeline<Fut>
impl<Fut, T, E> AsyncErrorPipeline<Fut>
Sourcepub fn with_context<C>(
self,
context: C,
) -> AsyncErrorPipeline<impl Future<Output = Result<T, ComposableError<E>>>>where
C: IntoErrorContext,
pub fn with_context<C>(
self,
context: C,
) -> AsyncErrorPipeline<impl Future<Output = Result<T, ComposableError<E>>>>where
C: IntoErrorContext,
Adds a context that will be attached to any error.
The context is only attached when an error occurs.
Note: if you pass an already-formatted String (e.g. format!(...)),
that formatting still happens eagerly before calling .with_context(...).
§Arguments
context- Any type implementingIntoErrorContext
§Examples
use error_rail::async_ext::AsyncErrorPipeline;
let pipeline = AsyncErrorPipeline::new(async { Err::<(), _>("error") })
.with_context("operation context");Sourcepub fn mark_transient_if<F>(
self,
classifier: F,
) -> AsyncErrorPipeline<impl Future<Output = Result<T, MarkedError<E, F>>>>
pub fn mark_transient_if<F>( self, classifier: F, ) -> AsyncErrorPipeline<impl Future<Output = Result<T, MarkedError<E, F>>>>
Marks the error as transient or permanent based on a closure.
This allows for flexible retry control without implementing the crate::traits::TransientError
trait for the error type.
§Arguments
classifier- A closure that returnstrueif the error should be treated as transient
§Examples
use error_rail::prelude_async::*;
use error_rail::types::MarkedError;
async fn example() -> Result<(), MarkedError<String, impl Fn(&String) -> bool>> {
AsyncErrorPipeline::new(async { Err("error".to_string()) })
.mark_transient_if(|e: &String| e.contains("error"))
.finish()
.await
}Sourcepub fn with_context_fn<F, C>(
self,
f: F,
) -> AsyncErrorPipeline<impl Future<Output = Result<T, ComposableError<E>>>>where
F: FnOnce() -> C,
C: IntoErrorContext,
pub fn with_context_fn<F, C>(
self,
f: F,
) -> AsyncErrorPipeline<impl Future<Output = Result<T, ComposableError<E>>>>where
F: FnOnce() -> C,
C: IntoErrorContext,
Adds a lazily-evaluated context using a closure.
The closure is only called when an error occurs, avoiding any computation on the success path.
§Arguments
f- A closure that produces the error context
§Examples
use error_rail::async_ext::AsyncErrorPipeline;
#[derive(Debug)]
struct User;
#[derive(Debug)]
struct ApiError;
async fn fetch_user(_id: u64) -> Result<User, ApiError> {
Err(ApiError)
}
let id = 42u64;
let _pipeline = AsyncErrorPipeline::new(fetch_user(id))
.with_context_fn(|| format!("user_id: {}", id));Sourcepub fn map<U, F>(
self,
f: F,
) -> AsyncErrorPipeline<impl Future<Output = Result<U, E>>>
pub fn map<U, F>( self, f: F, ) -> AsyncErrorPipeline<impl Future<Output = Result<U, E>>>
Transforms the success value using a mapping function.
Sourcepub fn step<U, F>(
self,
f: F,
) -> AsyncErrorPipeline<impl Future<Output = Result<U, E>>>
pub fn step<U, F>( self, f: F, ) -> AsyncErrorPipeline<impl Future<Output = Result<U, E>>>
Transforms the pipeline using a fallible function.
This is an alias for and_then.
Sourcepub fn fallback(
self,
value: T,
) -> AsyncErrorPipeline<impl Future<Output = Result<T, E>>>
pub fn fallback( self, value: T, ) -> AsyncErrorPipeline<impl Future<Output = Result<T, E>>>
Attempts to recover from an error using a fallback value.
Sourcepub fn recover_safe<F>(
self,
f: F,
) -> AsyncErrorPipeline<impl Future<Output = Result<T, E>>>
pub fn recover_safe<F>( self, f: F, ) -> AsyncErrorPipeline<impl Future<Output = Result<T, E>>>
Attempts to recover from an error using a safe recovery function.
Sourcepub fn with_retry_context(
self,
attempt: u32,
) -> AsyncErrorPipeline<impl Future<Output = Result<T, ComposableError<E>>>>
pub fn with_retry_context( self, attempt: u32, ) -> AsyncErrorPipeline<impl Future<Output = Result<T, ComposableError<E>>>>
Adds a tag indicating this error was retried.
Source§impl<Fut, T, E> AsyncErrorPipeline<Fut>
impl<Fut, T, E> AsyncErrorPipeline<Fut>
Sourcepub async fn finish_boxed(self) -> Result<T, Box<ComposableError<E>>>
pub async fn finish_boxed(self) -> Result<T, Box<ComposableError<E>>>
Completes the pipeline and returns a boxed error result.
This is the recommended way to finish a pipeline when returning from a function, as it provides minimal stack footprint.
§Examples
use error_rail::prelude_async::*;
async fn example() -> BoxedResult<i32, &'static str> {
AsyncErrorPipeline::new(async { Err("error") })
.with_context("operation failed")
.finish_boxed()
.await
}Sourcepub fn map_err<F, E2>(
self,
f: F,
) -> AsyncErrorPipeline<impl Future<Output = Result<T, ComposableError<E2>>>>
pub fn map_err<F, E2>( self, f: F, ) -> AsyncErrorPipeline<impl Future<Output = Result<T, ComposableError<E2>>>>
Maps the error type using a transformation function.
§Arguments
f- A function that transformsComposableError<E>toComposableError<E2>
§Examples
use error_rail::async_ext::AsyncErrorPipeline;
let pipeline = AsyncErrorPipeline::new(async { Err::<(), _>("error") })
.with_context("context")
.map_err(|e| e.map_core(|_| "new error"));