我尝试将错误类型SqlxError
转换为 并将anyhow::Error
其装箱为 ,然后恢复原始错误类型Box<dyn std::error::Error + Send + Sync + 'static>
。但是,类型信息似乎被删除了,向下转型失败了。
use std::error::Error as StdError;
use std::fmt;
#[derive(Debug)]
struct SqlxError {
message: String,
}
impl fmt::Display for SqlxError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "SQLx Error: {}", self.message)
}
}
impl StdError for SqlxError {}
fn main() {
// Create sqlx::Error
let sqlx_error = SqlxError {
message: "Database connection failed".to_string(),
};
// Convert to anyhow::Error
let anyhow_error = anyhow::Error::new(sqlx_error);
// Convert to Box<dyn StdError>
let boxed_error: Box<dyn StdError + Send + Sync + 'static> = anyhow_error.into();
// Now try to recover
let recovered_error = anyhow::Error::from_boxed(boxed_error);
// work well! output: SqlxError { message: "Database connection failed"}
dbg!(&recovered_error);
if let Some(sqlx_err) = recovered_error.downcast_ref::<SqlxError>() {
println!("Successfully downcast to SqlxError: {:?}", sqlx_err);
println!("Error message: {}", sqlx_err);
} else {
println!("Failed to downcast to SqlxError");
println!("Actual error: {}", recovered_error);
}
}
如下面的输出所示dbg!
,数据仍然是SqlxError
,但是downcast_ref::<SqlxError>()
失败了。
[src/main.rs:31:5] &recovered_error = SqlxError {
message: "Database connection failed",
}
我的理解是,转换anyhow::Error into Box<dyn StdError>
会消除任何包装器以及以后通过恢复原始类型的能力anyhow::Error
。
SqlxError
转换后,有什么方法可以从盒装特征对象中恢复原始错误类型吗anyhow::Error
?