如何让返回XMLError的方法兼容anyhow::Error?
问题:如何将XMLError转换为anyhow::Error?
我使用xml-builder库的XMLElement编写了以下代码:
use anyhow::Result; use xml_builder::XMLElement; fn foo() -> Result<()> { let mut v = XMLElement::new("v"); v.add_child(XMLElement::new("e"))?; Ok(()) }
这段代码无法编译,报错信息如下:
error[E0277]: the trait bound `XMLError: StdError` is not satisfied --> src/xml.rs:78:41 | 78 | v.add_child(XMLElement::new("e"))?; | ^ the trait `StdError` is not implemented for `XMLError` | = help: the following other types implement trait `FromResidual<R>`: <Result<T, F> as FromResidual<Result<Infallible, E>>> <Result<T, F> as FromResidual<Yeet<E>>> = note: required for `anyhow::Error` to implement `From<XMLError>` = note: required for `Result<std::string::String, anyhow::Error>` to implement `FromResidual<Result<Infallible, XMLError>>`
我尝试用.map_err(|e| anyhow::Error::new(e))转换错误,但没有效果,请问该如何将XMLError转换为anyhow::Error?
解决方法
问题核心是XMLError没有实现标准库的StdError trait,而anyhow的Error类型默认要求错误类型实现该trait才能通过?自动转换。这里提供两种可行的解决方式:
方法一:用anyhow!宏手动包装错误
直接捕获XMLError并用anyhow!宏将其转为anyhow::Error,这样就能正常使用?:
use anyhow::{anyhow, Result}; use xml_builder::XMLElement; fn foo() -> Result<()> { let mut v = XMLElement::new("v"); v.add_child(XMLElement::new("e")).map_err(|e| anyhow!(e))?; Ok(()) }
方法二:为XMLError实现From转换trait
如果XMLError是库的公共类型,可以在你的代码中实现From<XMLError> for anyhow::Error,之后就能直接用?自动转换,无需每次手动包装:
use anyhow::{Error, Result}; use xml_builder::{XMLElement, XMLError}; impl From<XMLError> for Error { fn from(e: XMLError) -> Self { // 可以自定义错误信息,保留原错误的上下文 Self::msg(format!("XML构建错误: {}", e)) } } fn foo() -> Result<()> { let mut v = XMLElement::new("v"); v.add_child(XMLElement::new("e"))?; Ok(()) }
注意:如果XMLError是库的私有类型,无法在外部实现转换trait,此时优先使用方法一。
内容的提问来源于stack exchange,提问作者yegor256
相关产品推荐
相关产品推荐

