Skip to main content

Many

Struct Many 

Source
pub struct Many {
    pub message: Cow<'static, str>,
    pub causes: Vec<Box<dyn Error + Send + Sync + 'static>>,
    pub location: Option<&'static Location<'static>>,
}
Expand description

An error type that can have multiple simultaneous causes.

Unlike scoped_error::Error which has a single causal chain, Many stores multiple independent errors. This is useful for:

  • Parallel operations where multiple tasks may fail
  • Validation that collects all errors before reporting
  • Operations with multiple independent failure modes

The source method returns the first cause for compatibility with the standard error interface. Use causes or the tree-formatted ErrorReport to access all errors.

§Example

use scoped_error::{Error, Many, expect_error};
use std::thread;

fn parallel_work() -> Result<Vec<()>, Many> {
    let handles = vec![
        thread::spawn(|| task_a()),
        thread::spawn(|| task_b()),
    ];
     
    let results: Vec<_> = handles
        .into_iter()
        .map(|h| h.join().unwrap())
        .collect();
     
    Many::from_results("parallel tasks failed", results)
}

fn task_a() -> Result<(), Error> {
    expect_error("task A failed", || {
        some_fallible_op()?;
        Ok(())
    })
}

fn task_b() -> Result<(), Error> {
    expect_error("task B failed", || {
        some_fallible_op()?;
        Ok(())
    })
}

Fields§

§message: Cow<'static, str>

The primary error message describing the overall failure.

§causes: Vec<Box<dyn Error + Send + Sync + 'static>>

All independent causes of this error.

§location: Option<&'static Location<'static>>

Where this error was created.

Implementations§

Source§

impl Many

Source

pub fn new(msg: impl Into<Cow<'static, str>>) -> Self

Create a new Many with the given message.

The causes list starts empty. Use with_cause or from_results to populate it.

§Example
use scoped_error::Many;

let err = Many::new("validation failed");
Source

pub fn with_cause<E>(self, cause: E) -> Self
where E: Into<Box<dyn Error + Send + Sync + 'static>>,

Add a cause to this error.

Returns self for chaining.

§Example
use scoped_error::Many;

let err = Many::new("multiple failures")
    .with_cause(std::io::Error::other("disk full"))
    .with_cause(std::io::Error::other("network timeout"));
Source

pub fn causes(&self) -> &[Box<dyn Error + Send + Sync + 'static>]

Get all causes as a slice.

Use this to iterate over all errors when the tree-formatted report doesn’t provide enough control.

§Example
use scoped_error::Many;

let err = Many::new("example");
for (i, cause) in err.causes().iter().enumerate() {
    println!("Failure {}: {}", i, cause);
}
Source

pub fn from_results<T, E>( msg: impl Into<Cow<'static, str>>, results: impl IntoIterator<Item = Result<T, E>>, ) -> Result<Vec<T>, Self>
where E: Into<Box<dyn Error + Send + Sync + 'static>>,

Collect results, returning Ok if all succeeded, Err with all failures.

This is the primary way to construct a Many from multiple operations. If all results are Ok, returns Ok with all the success values. If any are Err, returns Err with a Many containing all the errors.

§Type Parameters
  • T: The success type of each result
  • E: The error type (must be convertible to the boxed error type)
§Example
use scoped_error::Many;

let results: Vec<Result<i32, std::io::Error>> = vec![
    Ok(1),
    Err(std::io::Error::other("fail 1")),
    Err(std::io::Error::other("fail 2")),
];

match Many::from_results("batch operation failed", results) {
    Ok(values) => println!("Success: {:?}", values),
    Err(e) => println!("{}\nCaused by {} errors", e, e.causes().len()),
}
Examples found in repository?
examples/multi.rs (line 16)
8fn fetch_all(urls: Vec<String>) -> Result<Vec<String>, Many> {
9    let handles: Vec<_> = urls
10        .into_iter()
11        .map(|url| thread::spawn(move || fetch(&url)))
12        .collect();
13
14    let results: Vec<_> = handles.into_iter().map(|h| h.join().unwrap()).collect();
15
16    Many::from_results("failed to fetch URLs", results)
17}
Source

pub fn from_errors<E>( msg: impl Into<Cow<'static, str>>, errors: impl IntoIterator<Item = E>, ) -> Self
where E: Into<Box<dyn Error + Send + Sync + 'static>>,

Create from an iterator of errors, with a message.

Unlike from_results, this always returns Err. Use when you already know you have failures to report.

§Example
use scoped_error::Many;

let errors: Vec<std::io::Error> = vec![
    std::io::Error::other("error 1"),
    std::io::Error::other("error 2"),
];

let err = Many::from_errors("validation failed", errors);
Examples found in repository?
examples/multi_validation.rs (line 44)
28fn validate_user(input: &UserInput) -> Result<(), Many> {
29    let mut errors = Vec::new();
30
31    if input.name.is_empty() {
32        errors.push(ValidationError::new("name is required"));
33    }
34    if input.email.is_empty() {
35        errors.push(ValidationError::new("email is required"));
36    }
37    if input.age < 18 {
38        errors.push(ValidationError::new("must be 18 or older"));
39    }
40
41    if errors.is_empty() {
42        Ok(())
43    } else {
44        Err(Many::from_errors("user validation failed", errors))
45    }
46}
Source

pub fn is_empty(&self) -> bool

Returns true if there are no causes.

An empty Many is unusual but possible if constructed directly. Operations like from_results never create empty errors.

Source

pub fn len(&self) -> usize

Returns the number of causes.

Source§

impl Many

Source

pub fn with_message(self, msg: impl Into<Cow<'static, str>>) -> Self

Replace the message, returning self for chaining.

§Example
use scoped_error::Many;

let errors: Vec<std::io::Error> = vec![/* ... */];
let err = Many::from(errors)
    .with_message("custom batch operation failed");

Trait Implementations§

Source§

impl Debug for Many

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats using the error report for human-readable output.

Source§

impl Display for Many

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Displays the message with location and cause count.

Format: "{message}, at {location} ({n} causes)" or "{message} ({n} causes)" if location is None.

Source§

impl Error for Many

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the first cause, if any.

This provides compatibility with the standard Error trait’s single-chain model. To access all causes, use causes or the tree-formatted error report.

Returns None if there are no causes.

1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0:

use the Display impl or to_string()

1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl<E> From<Vec<E>> for Many
where E: Into<Box<dyn Error + Send + Sync + 'static>>,

Source§

fn from(errors: Vec<E>) -> Self

Convert a vector of errors into many.

The message defaults to “Multiple errors occurred”. Use with_message or new + with_cause for custom messages.

Auto Trait Implementations§

§

impl Freeze for Many

§

impl !RefUnwindSafe for Many

§

impl Send for Many

§

impl Sync for Many

§

impl Unpin for Many

§

impl UnsafeUnpin for Many

§

impl !UnwindSafe for Many

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> ErrorExt for T
where T: Error + 'static,

Source§

fn report(&self) -> ErrorReport<'_>

Generate a formatted error report for this error. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.