3 个版本 (破坏性更新)
0.3.0 | 2023年6月1日 |
---|---|
0.2.0 | 2023年5月15日 |
0.1.0 | 2019年9月6日 |
在 Rust 模式 中排名 #1047
每月下载量 22 次
9KB
144 行
Except
唯一的 Error
。
目前仅在 nightly 工具链中可用。
为什么?
Rust 的官方错误处理方法是 Result<T, E> where E: Error
。
但是 Error 太复杂,各种类型需要转换,每个 crate 都有自己的 Error 集合。
更糟糕的是,会出现枚举嵌套,例如
enum BazError {
IO(std::io::Error),
}
enum BarError {
IO(std::io::Error),
Baz(BazError),
}
enum FooError {
IO(std::io::Error),
Bar(BarError),
}
这里出现了多少次 std::io::Error
?
anyhow::Error
很好,但它通常只用于应用。
解决方案
这只是个人观点。
实际上,Error 只包含以下元素
type
:自动生成的 id,用于确定 Error 是否为某种类型。sub_type
:自动生成的 id,用于确定 Error 是否为某种子类型,用于补充类型。message
:描述 Error 的字符串。data
:可选的 Error 数据。backtrace
:Error 调用栈。source
:可选的前一个 Error。
对于 Rust,message
、、backtrace
source
已存在于 std::error::Error
中。
因此,我更喜欢自动生成 type
,我认为 TypeId
是一个解决方案。
对于 data
,我没有最好的想法,因为它的类型可能各不相同。为了实现只有一个 Error,我选择在内部使用 Box<dyn Any>
来保存它。
示例
use except::ErrorBuilder;
pub struct MyErrorKind;
pub fn foo() -> except::Result<()> {
Err(ErrorBuilder::new::<MyErrorKind>().message("this is my error").build())
}
pub fn main() {
if let Err(ex) = foo() {
if ex.is::<MyErrorKind>() {
eprintln!("my error detected: {:?}", ex);
}
}
}
许可证
Apache-2.0