无论如何:返回嵌套/包装错误

问题描述 投票:0回答:2
use anyhow::Context;

fancy_module::run()
.await
.with_context(|| {
    format!("An error has been found")
})?;

据我了解,当

run
返回错误时,我们返回“已发现错误”。但这个消息并没有什么实际意义。我还想返回运行返回的错误。像
format!("An error has been found {}", e)
之类的东西。如何让
e
返回
run

我可以用多行代码来做到这一点。通过获取

run
的结果,然后使用
match
语句。有更好的方法吗?

rust error-handling
2个回答
7
投票

据我了解,当 run 返回错误时,我们返回“已发现错误”。

不正确!

context
with_context
在底层错误值周围创建一个包装器以引入额外的上下文,但原始错误保留在其中!

一旦您尝试显示错误,您将看到类似的内容:

Error: An error has been found

Caused by:
    No such file or directory (os error 2)

(这也表明“已发现错误”对于创建附加上下文来说是一个糟糕的选择。)

我还想返回运行返回的错误。类似于

format!("An error has been found {}", e)

这在过去曾经是一个合理的设计决策,但当前的错误类型设计指南是反对包括显示消息中的源错误,除非该源错误在源错误链中也无法访问。上下文方法 will 将错误放入源链中,因此不建议将该错误的消息包含到顶级错误的消息中。

如何让

e
返回
run

请参阅

chain
方法来遍历源错误链,从而使您能够了解根本原因。尽管如此,无论如何,错误类型大多被设计为不透明的。如果您需要更好地反思错误的含义或更容易地对错误进行模式匹配,请考虑使用结构错误类型而不是
anyhow::Error
snafu
thiserror
可以帮助您构建它们)。

另请参阅:


0
投票

不正确访问错误消息(这很容易做到)可能会让您认为错误消息没有传播到父函数。

if let Err(e) = fancy_function::run().await.context("An error has been found")? {
  let msg: String = format!("{}", e.to_string());
  // contains ONLY "An error has been found"
  let stacktrace: String = format!("{:?}", e);
  // contains the numbered list of context messages that lead to the error
}
© www.soinside.com 2019 - 2024. All rights reserved.