Скала-способ справиться с условиями в для-понимания?

Я пытаюсь создать аккуратную конструкцию с пониманием бизнес-логики, построенной на фьючерсах. Вот пример, который содержит рабочий пример, основанный на обработке исключений:

(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 способ справиться с вещами. Есть лучший способ сделать это?

Обратите внимание, что эти ошибки происходят из разных источников - некоторые находятся на бизнес-уровне («проверка владения»), а некоторые - на уровне контроллера («авторизация»), а некоторые - на уровне базы данных («сущность не найдена»). Таким образом, подходы, когда вы выводите их из одного общего типа ошибки, могут не работать.

Ответы на вопрос(3)

Ваш ответ на вопрос