【发布时间】:2019-06-13 19:51:14
【问题描述】:
我正在创建一个与服务对话的控制器。控制器(基于 Play 库AbstractController)接受一个隐式请求并返回一个Future[Result]。该服务收到一个请求并返回一个Future[Model]。我有一些条件要防止创建模型。例如,如果用户没有访问权限,则不应创建任何模型。
def create(): Action[JsValue] = Action(parse.tolerantJson).async { implicit request: Request[JsValue] =>
val modelOpt: Option[Future[Result]] = // I've tried Future[Result] here too
for {
attributes <- (request.body \ "data" \ "attributes").validate[JsObject].asOpt
userOpt = (request.body \ "data" \ "attributes" \ "user-name").validate[String].asOpt
user <- userOpt
model <- service1.createModel(user) // Create Model returns type of Future[Model], so this should flatMap to Model
} yield {
val permission = checkPermission(user) // Returns true or false, depending on if the user is permissioned
(userOpt, permission) match {
case (Some(_), true) => Ok(model)
case (Some(_), false) => Forbidden
case (None, _) => NotFound
case (_, false) => Forbidden
}
}
modelOpt.getOrElse(Future { InternalServerError })
}
但是,编译器抱怨说它需要一个Option[Future[Result]],它收到一个Future[Result](可能是因为我为modelOpt 提供的类型)。但是,我认为如果 Json 无法验证它会给我None,所以我认为外部类型确实必须是一个选项。谁能告诉我这是怎么回事?
【问题讨论】:
-
如果您可以将代码缩减为 minimal reproducible example,这可能会有所帮助。切线:
Future { InternalServerError }不会因 InternalServerError 而失败;你想要Future { throw InternalServerError },或者更好的是Future.failed(InternalServerError)。 -
你能发布完整的错误吗?
-
如果 service1.createModel(user) 返回 Future[A],而其他从理解返回 Option[T] 它不兼容,因为你应该只使用相同的幺半群。
-
我不认为 Future.failed 会起作用,因为
InternalServerError是不可抛出的。 @BrianMcCutchon
标签: scala playframework future for-comprehension