Scala 如何绘制失败的未来预测图
在下面的代码中,函数应该返回Scala 如何绘制失败的未来预测图,scala,playframework-2.6,silhouette,Scala,Playframework 2.6,Silhouette,在下面的代码中,函数应该返回Future[Result]的实例,但我不能这样做。代码查询数据库,数据库返回Future[User]。我认为我能够描绘未来的成功部分,但不能正确描绘失败部分。请参阅函数末尾的注释 def addUser = silhouette.UserAwareAction.async{ implicit request => { val body: AnyContent = request.body val jsonBody: Option[JsValue
Future[Result]
的实例,但我不能这样做。代码查询数据库,数据库返回Future[User]
。我认为我能够描绘未来的成功部分,但不能正确描绘失败部分。请参阅函数末尾的注释
def addUser = silhouette.UserAwareAction.async{ implicit request => {
val body: AnyContent = request.body
val jsonBody: Option[JsValue] = body.asJson
//check for message body. It should be json
jsonBody match {
case Some(json) => { //got json in message body.
val readableString: String = Json.prettyPrint(json)
println(s"received Json ${readableString}")
val userProfile: Option[UserProfile] = json.asOpt[UserProfile] //check if json conforms with UserProfile structure
userProfile match {
case Some(profile) => { //json conforms to UserProfile.
println(s"received profile ${profile}")
val loginInfo = LoginInfo(CredentialsProvider.ID, profile.externalProfileDetails.email)
println(s"checking if the user with the following details exists ${loginInfo}")
val userFuture: Future[Option[User]] = userRepo.find(loginInfo) // userFuture will eventually contain the result of database query i.e Some(user) or None
userFuture.map { user:Option[User] => { //Future successful
case Some(user) => { //duplicate user
println("duplicate user" + user)
Future { Ok(Json.toJson(JsonResultError("duplicate user"))) }
}
case None => { //unique user
Future { Ok(Json.toJson(JsonResultSuccess("Not duplicate user"))) }
}
}
}
/***This is the part I am unable to code. I suppose the addUser method expect that the last statement (its return value) is Future{....} but it seems that they way I have coded it, it is not the case. If I remove this code and just type Future { Ok(Json.toJson(JsonResultSuccess("Internal Server Error"))) } then code compiles. But that logic is not correct because then this message will be sent all the time, not when the future fails!***/
val userFailedFuture:Future[Throwable] = userFuture.failed
userFailedFuture.map {x=> Future { Ok(Json.toJson(JsonResultSuccess("Internal Server Error"))) }}
}
//Json doesn't conform to UserProfile
case None => Future { Ok(Json.toJson(JsonResultError("Invalid profile"))) } /*TODOM - Standardise error messages. Use as constants*/
}
}
//message body is not json. Error.
case None => Future { Ok(Json.toJson(JsonResultError("Invalid Body Type. Need Json"))) }/*TODOM - Standardise error messages. Use as constants*/
}
}
}
您不必在将来包装您的结果,因为您已经从“未来价值”中进行了评估,简单来说,这样做可以:
futureValue.map{value => //RESULT
}
在将来处理错误时,建议使用recover和map-like:
futureValue.map{value => //RESULT
}.recover{case ex: Exception => //RESULT
}
如果结果已经在映射或恢复块中,则以后无需对其进行包装。作为地图之外的最终结果,未来的恢复将是未来[结果]。因此,如果您包装另一个未来,它将成为未来[未来[结果]。您不必在未来包装您的结果,因为您已经在根据未来价值进行评估,这将做到:
futureValue.map{value => //RESULT
}
在将来处理错误时,建议使用recover和map-like:
futureValue.map{value => //RESULT
}.recover{case ex: Exception => //RESULT
}
如果结果已经在映射或恢复块中,则以后无需对其进行包装。作为地图之外的最终结果,未来的恢复将是未来[结果]。所以,如果你包装另一个未来,它将成为未来[未来[结果]。同意@geek94的答案。 一项修正案:
不清楚您使用的是什么库,但在大多数情况下,不需要显式调用
future.recover
。每个体面的http库(例如akka http)都将失败的未来视为InternalServerError 同意@geek94的回答。
一项修正案:
不清楚您使用的是什么库,但在大多数情况下,不需要显式调用
future.recover
。每个体面的http库(例如akka http)都将失败的未来视为InternalServerError 谢谢。因此,我删除了map
中的Future
和中的recover
。我现在得到以下错误:error:(96,59)扩展函数缺少参数类型匿名函数的参数类型必须完全已知。(SLS 8.5)预期类型为:play.api.mvc.Result userFuture.map{(userOption:Option[User])=>{
就是这样。这是一个使用剪影
安全库的Playframework
应用程序。据我所知,映射
正在返回Ok
,类型为结果
。但我不明白编译器为什么会抱怨。如果遇到错误,您需要在未来更改代码块ure.map.change[userFuture.map{(userOption:Option[User])=>{]改为->[userFuture.map{case Some(User)=>//work;case None=>}]行得通。.recover
now.谢谢。你是个天才!尽管我不明白它为什么行得通?事实上,看看Scala文档,map的例子是val g=f map{x:String=>x+“现在是!”
。那么为什么我必须删除userOption:Option[User]
?上面的错误是,您在声明变量后直接尝试使用match case(也就是说,您可以像上面那样做,或者如果您想遵循您的模式,则必须执行此操作->future.map{value:Option[User]=>value match{case Some(User)=>case None=>/})谢谢。因此我在map
和中删除了Future
和.recover
。我现在得到以下错误错误:(96,59)扩展函数缺少参数类型匿名函数的参数类型必须完全已知。(SLS 8.5)预期类型为:play.api.mvc.Result userFuture.map{(userOption:Option[User])=>{
就是这样。这是一个使用剪影
安全库的Playframework
应用程序。据我所知,映射
正在返回Ok
,类型为结果
。但我不明白编译器为什么会抱怨。如果遇到错误,您需要在未来更改代码块将[userFuture.map{(userOption:Option[User])=>{]改为->[userFuture.map{case Some(User)=>//work;case None=>}]有效。.recover
now.谢谢。你是个天才!尽管我不明白它为什么有效?事实上,看看Scala文档,map的示例是val g=f map{x:String=>x+”是now!}
。那么为什么我必须删除userOption:Option[User]
?上面的错误是,您在声明变量后直接尝试使用match case(也就是说,您可以像上面那样做,或者如果您想遵循您的模式,那么您必须执行此操作->future.map{value:Option[User]=>value match{case Some(User)=>案例无=>/})