#error #multiple #error-handling #macro #propagate #action

multiple_errors

传播多个错误而不是只传播第一个错误

2 个稳定版本

1.1.0 2024 年 4 月 8 日
1.0.0 2024 年 4 月 8 日

#1115 in Rust 模式

MIT/Apache

15KB
187

multiple_errors

传播多个错误而不是只传播第一个错误。

描述

Rust 的 ? 运算符和 Iterator::collect::<Result<_, _>> 在遇到第一个错误时提前返回。然而,有时 我们想执行多个独立操作,然后一次性报告所有错误。或者如果至少有一个错误,则将所有结果都转换为错误。

此包涵盖这些用例,旨在成为一个易于搜索的 "枢纽",用于

  • 更多的 "大量错误处理" 功能
  • 关于其他包中相关功能的了解

multiple_errors 视为 itertools。它也是一个轻量级的 "纯逻辑" 包,无依赖项,应该适用于 no_std 和旧的 MSRV。我还没有做这个,如果您需要这个功能,请提出一个问题或发起一个 pull request。

示例

use multiple_errors::{fail_all_vec, return_multiple_errors, CollectVecResult};
use multiple_errors::testing_prelude::*;

assert_eq!(
    [Err(ErrA), Ok(A), Err(ErrA)].into_iter().collect_vec_result(),
    // Collected all errors, not just the first one
    Err(vec![ErrA, ErrA])
);

let err = fail_all_vec(
    vec![Ok(A), Err(ErrA), Ok(A)],
    |res| res.err().map(HighLevelErr::from).unwrap_or(HighLevelErr::B(ErrB))
);
// Same length as the original, each element turned into an error.
assert_eq!(err, Err(vec![ErrB.into(), ErrA.into(), ErrB.into()]));

fn a_b_c() -> Result<(A, B, C), Vec<HighLevelErr>> {
    return_multiple_errors!(
        let mut errors: Vec<HighLevelErr> = vec![];
        // Get some `Result`s:
        let a = action_a();
        let b = action_b();
        let c = action_c();
        if_there_are_errors {
            // Already converted and collected
            return Err(errors);
        }
    );
    // Already unwrapped
    Ok((a, b, c))
}

类似包

  • frunk::validated::Validated

    Validated 要么是持有 HList 的 Ok,要么是持有收集到的错误向量的 Err。

    它实现了与 return_multiple_errors! 相似的目标,但以一种更抽象、类型密集和可组合的方式。

  • itertools::Itertools::partition_result 和更通用的 partition_map

    将结果序列分区为包含所有 Ok 元素的一个列表和另一个包含所有 Err 元素的一个列表。

    如果您需要两个列表,只需使用itertools。如果您在出现错误时丢弃Ok,可以使用返回Result<Vec<T>, Vec<E>>CollectVecResult::collect_vec_result()。这更精确且高效。

许可证

根据您的选择,受Apache License, Version 2.0MIT license的许可。

除非您明确声明,否则根据Apache-2.0许可证定义的,您有意提交以包含在此软件包中的任何贡献,都将按照上述方式双许可,没有任何附加条款或条件。

无运行时依赖