繁体   English   中英

有没有办法在任意 `&dyn std::error::Error` 特征对象上获取 SNAFU 的 `.backtrace()`?

[英]Is there a way to get SNAFU's `.backtrace()` on arbitrary `&dyn std::error::Error` trait objects?

RFC 2504将向所有std::error::Error添加所需的fn backtrace(&self) -> Option<&Backtrace> 这还没有准备好,所以现在, SNAFU ,一个错误帮助宏,通过将ErrorCompat特征绑定到宏生成的所有类型来填充它。 这允许在它每晚登陆 Rust 之前提供回溯支持。

但是,此ErrorCompat特征并未针对std::error::Error的所有实现者实现。 我希望——在一些通用的错误打印代码中——能够显示原因链以及与 SNAFU 错误被实例化的位置相关的堆栈跟踪。 不幸的是, source() function 返回&(dyn Error + 'static)

use std::error::Error as StdError;
use snafu::{ResultExt, ErrorCompat};

fn main() {
    let err: Result<(), _> = Err(std::io::Error::new(std::io::ErrorKind::Other, "oh no!"));

    let err = err.with_context(|| parse_error::ReadInput {
        filename: "hello"
    });

    let err = err.with_context(|| compile_error::ParseStage);

    // some generic error handling code
    if let Err(err) = err {
        // `cause` is type &(dyn std::error::Error + 'static)
        let cause = err.source().unwrap();

        if let Some(err) = /* attempt to downcast cause into &dyn snafu::ErrorCompat trait object */ {
            println!("{}", err.backtrace().unwrap());
        }
    }
}

pub mod compile_error {
    use snafu::{Snafu, Backtrace};
    #[derive(Debug, Snafu)]
    #[snafu(visibility(pub(super)))]
    pub enum Error {
        #[snafu(display("Error parsing code: {}", source))]
        ParseStage {
           source: crate::parse_error::Error,
           backtrace: Backtrace
        },
    }
}

pub mod parse_error {
    use snafu::{Snafu, Backtrace};
    #[derive(Debug, Snafu)]
    #[snafu(visibility(pub(super)))]
    pub enum Error {
        #[snafu(display("Could not read input {:?}: {}", filename, source))]
        ReadInput {
           filename: std::path::PathBuf,
           source: std::io::Error,
           backtrace: Backtrace
        },
    }
}

我查看了std::any::Any::downcast_ref但这是用于向下转换为结构,而不是将特征 object 向下转换为另一个特征 object。 我想避免在我的错误处理代码中列出所有可能的具体类型的 SNAFU 错误。

在 RFC 2504 (完全)实施之前,我可以冷冻自己,但肯定有一些方法可以做到这一点。

一个dyn ErrorError的方法,没有别的。 如果无法从这些方法中推断出回溯,那么这些信息还能从哪里来?

不幸的是, RFC 2504还没有稳定下来,所以如果你想等待的话,你需要进行低温冷冻直到至少 Rust 1.39。

似乎我错过了这一点,因为没有重新编译每晚的std文档,但是#![feature(backtrace)]现在每晚都在。 SNAFU 仍然需要添加对它的支持,所以我仍然坚持让这一切正常工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM