api - 编写处理异常的 Scala 方法签名的最佳方式

标签 api scala exception scalaz scalaz7

为了在 Scala 中处理异常,我更喜欢避免使用基本的 try/catch 并从 Scalaz 的 Validation 中受益(类似在某些情况下为 Either 类型)。

我的应用程序公开了一些服务。想象一下我的服务层中的这种方法(没有实际意义,但对概念有益)。它将 Buyer(购买者)与他的新 Car 相关联,如果所有规则都成功通过,则返回包含此关联的 Car:

def create(carDTO: CarDTO, buyerDTO: BuyerDTO): Validation[Either[TechnicalFailure, List[CarCreationFailure]], CarDTO]

说明:创建 Car 可能会导致两种异常类型之一:

  • 技术故障(例如,当数据库崩溃时)包装 Throwable 异常。
  • 业务失败(自定义应用程序的规则防止不一致,例如,Car 处于非法状态)。 CarCreationFailure 就是其中之一,当然可以通过更多精确 失败来扩展。

我的问题特别关注客户端,并专门处理不止一种潜在的业务失败

是否应该将返回类型 Validation[Either[TechnicalFailure, List[CarCreationFailure]], CarDTO] 替换为更简单的:ValidationNel[Throwable, CarDTO]/p>

注意这里的ValidationNel(将错误/异常累积到NonEmptyList)。

一个缺点是,新读者乍一看无法猜测此方法返回 TechnicalFailureCarCreationFailure(BusinessFailure< 的子类 所以);只是一个太可怕的Throwable

他将被迫对我的应用程序中包含的每个 Throwable 类型应用模式匹配,以确保不会忘记任何人... => 困惑。

在这些解决方案中,最干净的方法是什么,或者……其他方法?

最佳答案

在这种情况下,我个人使用一个名为 Tri 的自定义类,它的工作方式类似于 TryEither:

sealed trait Tri [+Value, +Problem] { ... }
final case class Good[+Value](v: Value) extends Tri[Value, Nothing] { ... }
final case class Bad[+Problem](p: Problem) extends Tri[Nothing, Problem] { ... }
final case class Ugly(th: Throwable) extends Tri[Nothing, Nothing] { ... }

用适当的方法来处理人们想要的最常见的操作。在这种情况下,我会简单地返回给客户端

Tri[CarDTO, List[CarCreationFailure]]

并根据需要将异常包装到自定义异常类中。这两者都是关于代码本身正常工作时可能发生或不发生的事情的预先说明,并且像往常一样留下未说明的异常情况,这些情况迟早需要处理,包括数据库错误之类的事情。然后你只是例如:

create(car, buyer) match {
  case Good(dto) => // Yay
  case Bad(xs) =>   // Handle list of car creation failures
  case Ugly(th) =>  // Handle exceptions
}

我不知道 Scalaz7 中有任何类似的功能,尽管您可以比在 Scalazless Scala 中更容易地构建这些片段(正如您所做的那样,但为什么不使用 \/?),因此您可能不太愿意创建这种三方错误处理类。

关于api - 编写处理异常的 Scala 方法签名的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16193302/

相关文章:

Scala 用于与 Future 一起使用的产量理解。如何等到 future 回来?

scala - 运行scala jar时出错

iphone - 未记录的 iphone 的 api 经历过

api - 具有 Multi-Tenancy 和共享资源的 RESTful API

Node.js 速率限制器身份验证 token 而不是 IP 地址

php - 我应该使用 PDO 在自己的数据库类中抛出异常吗?

C++ 异常抛出空类

python - 在 Flask API 中展平数组

scala - 扩展 scala 案例类而不需要不断重复构造函数值?

java - 应用程序在蓝牙发现期间崩溃