24个版本
0.6.3 | 2020年11月9日 |
---|---|
0.6.2 | 2019年10月16日 |
0.5.1 | 2019年10月9日 |
#16 in #longer
每月 53次下载
用于 mango-client
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
可以通过以下方式实现,利用从 &str
到 From
的转换。
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_or
或 ok_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
我们再次利用从 &str
到 From
的转换来返回一个 StrError
。
到 StrError
的 From
转换
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
转换也实现了对 &str
和 String
的支持,如前所述。
然而,对于其他错误类型,如果您想使用 ?
操作符,首先需要调用 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