什么是ZIO错误通道?如何了解其中的内容?

问题描述

ZIOhttps://zio.dev/)是一个scala框架,其核心是ZIO[R,E,A]数据结构,并且其站点提供了以下三个参数的信息:

ZIO

ZIO[R,A]数据类型具有三个类型参数:

  • R-环境类型。该效果需要一个R类型的环境。如果此类型参数为Any,则表示效果没有 要求,因为您可以使用任何值来运行效果(对于 例如,单位值())。
  • E-失败类型效果可能因类型为E的值而失败。某些应用程序将使用Throwable。如果此类型参数为 nothing,这意味着效果不会失败,因为没有 类型的值。
  • A-成功类型。该效果可能会因类型为A的值而成功。如果此类型参数为Unit,则表示效果不产生 有用的信息,而如果是nothing,则表示效果运行 永远(或直到失败)。

很容易得到A是什么:在正常情况下,它是函数返回的值,即为什么要为函数编写代码R是如此的依赖注入-一个有趣的话题,但是我们可以通过始终将其设置为ZIO来忽略它使用Any(实际上有一个IO[E,A] = ZIO[Any,A]库中的别名)。

因此,它仍然是E类型,用于错误(著名的错误通道)。我粗略地认为IO[E,A]Either[E,A]的一种,但是效果很好(很好)。

我的问题是:为什么在我的应用程序中应在所有位置使用错误通道?如何确定错误通道中应该包含的内容

解决方法

1 /为什么使用错误渠道进行效果管理?

作为开发人员,您最艰巨的任务之一就是确定什么是错误而应用程序中没有错误-或更确切地说,要发现故障模式:标称路径(即该代码的目标),什么?是应用程序以后可以通过某种方式处理的预期错误,以及应用程序无法处理的意外错误。对于该问题,没有确切的答案,它取决于应用程序和上下文,因此开发人员需要您自己决定。

但是最困难的任务是构建一个遵守诺言(您的诺言,因为您选择了错误和名义路径)的应用程序,这不足为奇,因此用户,管理员和开发人员-包括请在两周内让您满意-知道代码在大多数情况下的工作方式,而不必猜测并具有代理商来适应这种行为,包括响应错误。

这很困难,您需要一个系统的流程来处理所有可能的情况,而无需进行处理。

IO bi-monad(因此ZIO)中的错误通道可以帮助您完成该任务:IO monad可以帮助您跟踪效果,这是大多数问题的根源错误,错误通道会明确指出可能的错误情况,因此,如果可能,应用程序的其他部分有权使用它们来处理。 您将能够通过明确的故障模式以纯净,一致,可组合的方式管理您的效果。 此外,在ZIO的情况下,您可以非常轻松地轻松地导入非纯代码(如旧版Java):

val pure = ZIO.effect(someJavaCodeThrowingException)

2 /如何选择错误?

因此,错误通道提供了一种对what if?问题的答案进行编码的方法,以使开发该代码的开发人员能够继续使用。 “如果数据库关闭怎么办?” “有一个DatabaseConnectionError”。 但是对于您的用例和当前应用程序级别,所有what if都不相同。 “如果找不到用户怎么办?” -嗯,这可能是在“存储库”较低级别(如未找到任何内容的“查找”)完全可以预期的答案,或者在其他级别也可能是错误(例如在处理过程中)验证用户身份,它应该确实存在)。在第一种情况下,您可能不会使用错误通道:这是名义路径,有时您找不到东西。在第二种情况下,您可能会使用错误通道(UserNotFoundError)。

因此,正如我们所说,错误通道中的错误通常是针对您可能希望在应用程序中处理的what if问题,而不是该功能级别的问题。 DatabaseConnectionError的第一个示例可能会在应用程序中占据较高的位置,并导致诸如“请重试”之类的用户消息以及发给sysadmin的通知电子邮件(“快速查看,如果此处有问题,请注意”)。 UserNotFoundError可能会以登录表单中的错误消息的形式被管理,例如“错误的登录名或密码,请重试或通过该过程恢复凭据”。

因此,这些情况(标称误差和预期误差)是简单的部分。但是有一些what if问题,无论级别如何,您的应用程序都不知道如何回答。 “如果我在尝试分配该对象时遇到内存异常,该怎么办?” 我没有任何线索,实际上,即使有线索,这也不在乎我要处理的那个应用程序。因此,这些错误不会进入错误通道。我们称它们为失败,并在发生这些情况时使应用程序崩溃,因为该应用程序现在可能处于未知状态,危险的僵尸状态。

同样,该选择(标称路径/错误通道/故障)是您的选择:两个应用程序可以做出不同的选择。例如,一次性数据处理应用程序然后丢弃它可能会将所有非标称路径视为故障。有一个开发人员可以实时了解情况并确定是否重要(请参阅:Shell,Python以及大量使用了该策略的脚本-好的,有时甚至没有开发人员可以捕获错误:)。另一方面,Nasa开发人员将一切都放在了错误通道(+)中,甚至将内存损坏了。由于这是预期的错误,因此应用程序需要知道如何处理并继续。

(+)注意:AFAIK他们暂时不使用zio,但是即使在C语言中,关于什么是错误的决策过程也是相同的。

进一步讲,我(@ fanf42)在Scala.io会议上发表了演讲。 法语 here中提供了“应用程序中的错误错误管理”主题。是的,我知道是法语-但是可以用英语 here来获得幻灯片!而且您可以ping我(请参阅滑盖末端附近的联系信息)。