#error #error-message #traits #backtrace #context #object #dyn

extracterr

通过 dyn Error 特性对象传递上下文的辅助类型和特性

2个版本

0.1.1 2020年5月18日
0.1.0 2020年5月18日

#15 in #dyn

MIT/Apache

21KB
157

extracterr

Build Status Latest Version Rust Documentation

为将上下文与错误捆绑并稍后通过 dyn Error 特性对象提取上下文提供辅助。

此库的主要目的是通过 dyn Error 特性对象将上下文传递给错误报告器。这对于可能需要被叶错误捕获但又不属于任何单个错误消息的信息非常有用。回溯、http 状态码和帮助消息都是可以直接传递给错误报告器而不是在错误链中打印的上下文示例。

设置

[dependencies]
extracterr = "0.1"

快速入门示例

use backtrace::Backtrace;
use std::error::Error;
use extracterr::{Bundle, Bundled, Extract};

#[derive(Debug, thiserror::Error)]
#[error("Example Error")]
struct ExampleError;

let error = ExampleError;

// Capture a backtrace via `Default` and `From`
let error: Bundled<_, Backtrace> = error.into();

// Convert it to a trait object to throw away type information
let error: Box<dyn Error + Send + Sync + 'static> = error.into();

// first error in chain is the unerased version of the error `Bundled<ExampleError, Backtrace>`
assert!(error.downcast_ref::<Bundled<ExampleError, Backtrace>>().is_some());
assert_eq!("Example Error", error.to_string());
assert!(error.extract::<Backtrace>().is_none());

// Move to the next error in the chain
let error = error.source().unwrap();

// The second error in the chain is the erased version `Bundled<Erased, Backtrace>` which now
// works with downcasting, letting us access the bundled context
let backtrace = error.extract::<Backtrace>();
assert!(backtrace.is_some());

// The Display / Debug impls of the fake error that contains the bundled context print the
// context's type_name
assert_eq!(error.to_string(), std::any::type_name::<Backtrace>());

详细信息

此库提供的主要类型是 Bundled 类型,它将错误和上下文类型捆绑到新的错误中。此类型可以通过 From+DefaultBundle 构建,更多详细信息请查看Bundled 的文档。

此类型与错误类型模式配合得最好,如 std::io::Error 中所示。

use backtrace::Backtrace;
use extracterr::{Bundle, Bundled};

#[derive(Debug, thiserror::Error)]
#[error(transparent)]
struct Error {
    kind: Bundled<Kind, Backtrace>,
}

#[derive(Debug, thiserror::Error, Clone, Copy)]
enum Kind {
    #[error("could not enqueue item")]
    Queue,
    #[error("could not dequeue item")]
    Dequeue
}

impl Error {
    fn kind(&self) -> Kind {
        *self.kind.inner()
    }
}

impl From<Kind> for Error {
    fn from(kind: Kind) -> Self {
        Self { kind: Bundled::from(kind) }
    }
}

impl From<Bundled<Kind, Backtrace>> for Error {
    fn from(kind: Bundled<Kind, Backtrace>) -> Self {
        Self { kind }
    }
}

fn queue() -> Result<(), Error> {
    Err(Kind::Queue)?
}

fn dequeue() -> Result<(), Error> {
    Err(Kind::Dequeue).bundle(Backtrace::new())?
}

use extracterr::Extract;

let error = dequeue().unwrap_err();

// Convert it to a trait object to throw away type information
let error: Box<dyn std::error::Error + Send + Sync + 'static> = error.into();

assert!(error.downcast_ref::<Error>().is_some());
assert_eq!("could not dequeue item", error.to_string());
assert!(error.extract::<Backtrace>().is_none());

// Move to the next error in the chain
let error = error.source().unwrap();

let backtrace = error.extract::<Backtrace>();
assert!(backtrace.is_some());

一旦上下文被捆绑到错误链中,就可以通过 Extract 特性提取出来。查看 stable-eyre 的源代码,以了解 Extract 在错误报告器中的简单示例用法。

许可证

根据您的选择,在Apache License, Version 2.0MIT 许可证 下授权。
除非您明确说明,否则您根据 Apache-2.0 许可证定义的任何有意提交以包含在此库中的贡献,将根据上述方式双许可,不附加任何额外条款或条件。

无运行时依赖