FHO Error
类型与 ffx_error
在子工具边界,我们有一个由 ffx
库定义的错误类型,作为向主 ffx
工具指明该错误是否应报告为 bug 的一种方式。
在旧版插件系统中,这是使用 ffx_error
或 ffx_bail
宏来指示的,表示应直接向用户报告错误,并将任何其他详细信息分流到日志。任何其他 anyhow
错误都会被视为 BUG
,其中包含严重警告和有关在日志中查找位置的信息。
虽然这种方法仍然可行,并且新的错误类型会正确地从 anyhow
错误中吸收这些信息,但我们并不建议继续以这种方式执行操作。这会让人感到困惑和模糊,并且当人们通过其他工具学习如何编写工具时,往往并不知道为何以其原有方式使用这些宏。
将错误转换为 fho::Error
与 anyhow
不同,fho 的错误类型不会尝试直接吸收任何错误。您应改用 FfxContext
特征中的方法,指明您希望如何处理错误。
如果您希望错误被视为用户错误,可以使用 user_message
或 with_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()?;