[英]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 Error
有Error
的方法,没有别的。 如果无法从这些方法中推断出回溯,那么这些信息还能从哪里来?
不幸的是, RFC 2504还没有稳定下来,所以如果你想等待的话,你需要进行低温冷冻直到至少 Rust 1.39。
似乎我错过了这一点,因为没有重新编译每晚的std
文档,但是#![feature(backtrace)]
现在每晚都在。 SNAFU 仍然需要添加对它的支持,所以我仍然坚持让这一切正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.