我正在使用 Scala 开发一个应用程序。我正在尝试在应用程序中实现异常处理。我尝试使用Either
来处理异常。对于简单的情况,处理异常似乎就足够了。但是,当我需要通过连接从多个表中获取结果时,异常处理会产生比解决更多的问题。我的应用程序结构解释如下:
对定义所有数据库交互操作的数据库操作使用存储库模式。例如,我有一个中央存储库,它定义了findAll
、findById
、insert
、delete
、update
等exists
。我的findAll
方法签名已更改为Either[CustomException, List[TEntity]]
,类似findById
的方法类型是Either[CustomException, Option[TEntity]]
。
现在假设,如果我需要在我的方法中从数据库中获取员工,我将执行如下操作:
def getVehicleById(id:Long) = {
val vehicle = repository.findById(id)
//i have one-to-one mapping with Employee table for the driver of the vehicle
val driver = empRepository.findById(vehicle.driverId)
}
现在车辆的Either[CustomException, Option[Vehicle]]
类型是,司机的类型是Either[CustomException, Employee]
如果我在得到结果后需要做更多的操作,我必须使用右/左大小写,然后再做。问题是,可能在 Right case 中,我可能需要加入另一个表,这使得结果再次成为Either[CustomException, Entity]
。如果该操作发生任何错误,我需要再次使用 try catch 块。我觉得当代码复杂度增加时,这种处理变得非常难以管理,而且我会有很多样板代码来处理这些情况,这违背了 Scala 原则本身。
所以我的问题是,如何在没有太多样板代码的情况下以更好的方式处理异常。
注意:我来自 Java 背景,现在只在 Scala 上工作了几个月。
编辑
使用 Try 添加示例代码:此示例非常接近我的要求。
import scala.util._
def checkTry:Try[List[Int]] = Success(List(2))
def checkTryStr:Try[String] = Success("Asd")
def getVehicleWithDriver = for {
a <- checkTry
c <- a
b <- checkTryStr
}yield {
(c,b)
}
getVehicleWithDriver
但是使用上面的代码,我得到了编译错误。
Error:(9, 6) type mismatch; found : scala.util.Try[(Int, String)] required: scala.collection.GenTraversableOnce[?] b <- checkTryStr ^ Error:(9, 6) type mismatch; found : scala.util.Try[(Int, String)] required: scala.collection.GenTraversableOnce[?] b <- checkTryStr ^ Error:(8, 6) type mismatch; found : List[Nothing] required: scala.util.Try[?] c <- a ^