#error #error-string #longer #replace #anyhow #thiserror #error-context

已弃用 strerror

一种基于字符串的错误类型。不再开发。推荐替代方案:Anyhow和Thiserror库。

24个版本

0.6.3 2020年11月9日
0.6.2 2019年10月16日
0.5.1 2019年10月9日

#16 in #longer

Download history 6/week @ 2024-04-01

每月 53次下载
用于 mango-client

MIT/Apache

21KB
278

strerror

一种基于字符串的错误类型。 不再开发。推荐替代方案:Anyhow和Thiserror库。

文档

请参阅包含的rustdoc文档或访问https://docs.rs/strerror

请注意,在本地构建文档时,您目前需要一个nightly编译器才能正确渲染RFC1946 intra-rustdoc链接。

许可证

该项目可根据您的选择在MIT许可证(LICENSE-MIT)或Apache许可证2.0(LICENSE-APACHE)下获得许可。


lib.rs:

一种基于字符串的错误类型。 不再开发。推荐替代方案:Anyhow和Thiserror库。

简介

此包提供了一种基于字符串的错误类型 StrError,它实现了 std::error::Error。它适用于简单的用例,其中您希望使用字符串错误以及/或将任何类型的现有错误装箱,为它们添加上下文。

StrError 在许多方面类似于 String,但它们也可能包含另一个错误,称为“来源”或“原因”。由于来源本身也可以有来源,因此来源形成错误链,每个错误都为前面的错误添加上下文。

当从 main 返回 StrError 时,其 Debug 实现导致命令行应用程序的输出如下所示

Error: ...
Caused by: ...
Caused by: ...
...

每个 "由...引起:" 行对应于来源链中的装箱错误。

前言

此包有一个前言,可以将您需要的一切一次性引入。

use strerror::prelude::*;

以下示例都假定使用前言。

创建 StrError

String 类似,创建 StrError 有许多方法。其中一些具有类似 String 的类似物,因此与它们并排展示。

// String                             // StrError
let str1 = "Error!".to_string();      let err1 = "Error!".into_error();
let str2 = String::from("Error!");    let err2 = StrError::from("Error!");
let str3: String = "Error!".into();   let err3: StrError = "Error!".into();
let str4 = format!("Error! #{}", 1);  let err4 = eformat!("Error! #{}", 1);

上述行都创建了没有“来源”或“原因”的 StrError。要创建带有来源的 StrError,可以使用 chain_error

use std::io::Error as IoError;

let source = IoError::from_raw_os_error(5);
let err = source.chain_error("I/O error occurred");

chain_error 方法调用链式调用在一起会创建一个错误链。

fn main() -> Result<(), StrError> {
    let err = "Base error".into_error()
        .chain_error("Higher level error")
        .chain_error("Application error");
    Err(err)
}

输出结果

Error: Application error
Caused by: Higher level error
Caused by: Base error

返回 Result

虽然 chain_error 方法直接添加了错误类型上下文,但我们可以通过 Err 变体值在 Result 中的 chain_err 方法来实现类似的功能。

use std::fs::File;

fn main() -> Result<(), StrError> {
    let file = "missing-file";
    let _ = File::open(file)                                // a Result
        .chain_err(|| format!("Failed to open {}", file))?; // main exits
    Ok(())
}

输出结果

Error: Failed to open missing-file
Caused by: No such file or directory (os error 2)

Result 通过 chain_err 转换为正确的类型,并将上下文应用于包装的错误。注意,在上面的示例中,chair_err 接收一个闭包,而不是直接接收一个 String。这样,只有在需要时才会执行 String 的构造。但是,不需要使用闭包,因为 chair_err 接受 String&str

Result 中返回一个新的 StrError 可以通过以下方式实现,利用从 &strFrom 的转换。


fn main() -> Result<(), StrError> {
    return Err("an error".into());
}

另一种选择是 into_err 方法,它将在一步中调用 into 并创建 Err 变体。


fn main() -> Result<(), StrError> {
    return "an error".into_err();
}

转换 Option

有时 None 代表应用程序错误,并且希望将 Option<T> 转换为一个 Result<T, StrError>。在这种情况下不需要特殊方法。可以使用 ok_orok_or_else

use std::env;

fn main() -> Result<(), StrError> {
    let _ = env::var_os("MISSING_VAR")    // an Option
        .ok_or("MISSING_VAR not found")?; // main exits
    Ok(())
}

输出结果

Error: MISSING_VAR not found

我们再次利用从 &strFrom 的转换来返回一个 StrError

StrErrorFrom 转换

From 转换已实现于大多数标准库错误类型,因此您可以从期望 Result<T, StrError> 的函数中直接返回一个 Result<T, StrError>,使用 ? 操作符。

use std::fs::File;

fn main() -> Result<(), StrError> {
    let file = "missing-file";
    let _ = File::open(file)?; // main exits
    Ok(())
}

输出结果

Error: std::io::Error
Caused by: No such file or directory (os error 2)

From 转换也实现了对 &strString 的支持,如前所述。

然而,对于其他错误类型,如果您想使用 ? 操作符,首先需要调用 chain_err 方法将 Result<T, E> 转换为 Result<T, StrError>。当然,您可以选择在函数的返回类型中使用 Box<dyn std::error::Error> 而不是 StrError,在这种情况下,? 将对所有错误类型都有效。

Deref

StrError 解引用到 String,因此您可以使用许多常规的 String 方法。

fn main() -> Result<(), StrError> {
    let mut err = "This is".into_error();
    *err += " an error";
    err.push_str(" message");
    Err(err)
}

输出结果

Error: This is an error message

遍历源链

可以遍历 StrError 的引用以检查其boxed源链。

use std::io::Error as IoError;

fn main() -> Result<(), StrError> {
    let err = IoError::from_raw_os_error(5)
        .chain_error("Failure reading disk")
        .chain_error("Application error");
    for e in &err {
        println!(
            "Error: {:31} Is StrError?: {}",
            e,
            e.downcast_ref::<StrError>().is_some()
        );
    }
    Ok(())
}

输出结果

Error: Application error               Is StrError?: true
Error: Failure reading disk            Is StrError?: true
Error: Input/output error (os error 5) Is StrError?: false

无运行时依赖