FFX 子工具中的错误

FHO Error 类型与 ffx_error

在子工具边界,我们有一个由 ffx 库定义的错误类型,作为向主 ffx 工具指明该错误是否应报告为 bug 的一种方式。

在旧版插件系统中,这是使用 ffx_errorffx_bail 宏来指示的,表示应直接向用户报告错误,并将任何其他详细信息分流到日志。任何其他 anyhow 错误都会被视为 BUG,其中包含严重警告和有关在日志中查找位置的信息。

虽然这种方法仍然可行,并且新的错误类型会正确地从 anyhow 错误中吸收这些信息,但我们并不建议继续以这种方式执行操作。这会让人感到困惑和模糊,并且当人们通过其他工具学习如何编写工具时,往往并不知道为何以其原有方式使用这些宏。

将错误转换为 fho::Error

anyhow 不同,fho 的错误类型不会尝试直接吸收任何错误。您应改用 FfxContext 特征中的方法,指明您希望如何处理错误。

如果您希望错误被视为用户错误,可以使用 user_messagewith_user_message 向其添加用户可见的上下文(同时保留错误链以用于诊断):

process(filename).with_user_message(|| format!("Failed to process {filename}"))?;

如果您希望将它视为 bug 处理,因为这实际上不应该发生,而且用户不太可能采取任何简单的操作来解决问题:

do_thing().bug()?;

这样可以强制了解向用户呈现错误的方式。

何时使用何种错误类型

没有必要或可能非常可取,将这种类型的错误贯穿整个代码库。您可能会继续使用 anyhow,最好是在库代码和工具的较低级别的部分中使用 thiserror。然后,您可以将这些错误转换为与 ffx 兼容的错误。

保持库代码的边界,以决定如何显示错误。建议您尽量将与用户互动相关的所有信息浅到此层,并将您需要的内容传递到更深的层,以便您在此处做出更好的决策。

该流程的一个极其简单的示例:

let stuff = get_user_input().user_message("Your input made no sense!")?;
stuff.act_on_it().bug()?;