Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何绘制失败的未来预测图_Scala_Playframework 2.6_Silhouette - Fatal编程技术网

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)=>案例无=>/})