Скала-способ справиться с условиями в для-понимания?
Я пытаюсь создать аккуратную конструкцию с пониманием бизнес-логики, построенной на фьючерсах. Вот пример, который содержит рабочий пример, основанный на обработке исключений:
(for {
// find the user by id, findUser(id) returns Future[Option[User]]
userOpt <- userDao.findUser(userId)
_ = if (!userOpt.isDefined) throw new EntityNotFoundException(classOf[User], userId)
user = userOpt.get
// authenticate it, authenticate(user) returns Future[AuthResult]
authResult <- userDao.authenticate(user)
_ = if (!authResult.ok) throw new AuthFailedException(userId)
// find the good owned by the user, findGood(id) returns Future[Option[Good]]
goodOpt <- goodDao.findGood(goodId)
_ = if (!good.isDefined) throw new EntityNotFoundException(classOf[Good], goodId)
good = goodOpt.get
// check ownership for the user, checkOwnership(user, good) returns Future[Boolean]
ownership <- goodDao.checkOwnership(user, good)
if (!ownership) throw new OwnershipException(user, good)
_ <- goodDao.remove(good)
} yield {
renderJson(Map(
"success" -> true
))
})
.recover {
case ex: EntityNotFoundException =>
/// ... handle error cases ...
renderJson(Map(
"success" -> false,
"error" -> "Your blahblahblah was not found in our database"
))
case ex: AuthFailedException =>
/// ... handle error cases ...
case ex: OwnershipException =>
/// ... handle error cases ...
}
Однако это может рассматриваться как нефункциональный или не Scala способ справиться с вещами. Есть лучший способ сделать это?
Обратите внимание, что эти ошибки происходят из разных источников - некоторые находятся на бизнес-уровне («проверка владения»), а некоторые - на уровне контроллера («авторизация»), а некоторые - на уровне базы данных («сущность не найдена»). Таким образом, подходы, когда вы выводите их из одного общего типа ошибки, могут не работать.