Ответ 1
Почему это не так, на самом деле имеет значение 100%. Если мы распространим код на несколько строк кода, вы поймете, почему:
def getStuff(userId: String) = Action(implicit request => {
Async {
val future = UserDao().getStuffOf(userId = userId).toList()
val mappedFuture = future.map {
stuffLst => Ok(stuffLst)
}
mappedFuture.recover { case _ => BadRequest("")}
}
})
Итак, UserDao().getStuffOf(userId = userId).toList()
возвращает вам будущее. Будущее представляет собой нечто, что, возможно, еще не произошло. Если эта вещь вызывает исключение, вы можете обработать это исключение в процессе восстановления. Однако в вашем случае ошибка происходит до того, как будущее будет даже создано, вызов UserDao().getStuffOf(userId = userId).toList()
бросает исключение, а не возвращает будущее. Поэтому призыв к восстановлению будущего никогда не будет выполнен. Это эквивалентно выполнению этого в Scala repl:
import scala.concurrent._
import scala.concurrent.duration._
import ExecutionContext.Implicits.global
var f = { throw new Exception(""); future { "foo" } map {_ => 2} recover { case _ => 1} }
Await.result(f, 1 nanos) }
Очевидно, что это не сработает, поскольку вы никогда не создавали будущее, в первую очередь, вызывали исключение, прежде чем код создавал будущее.
Итак, решение заключается в том, чтобы либо обернуть ваш вызов UserDao().getStuffOf(userId = userId).toList()
в блок catch try, либо выяснить, почему он не работает в любом методе, который вы вызываете, и улавливать исключение там, и возвращать неудавшееся будущее.