[英]Scala Strange Error with Partial Functions
我有以下代碼由於某種奇怪的原因而無法編譯!
def createNewPowerPlant = Action.async(parse.tolerantJson) { request =>
request.body.validate[PowerPlantConfig].fold(
errors => {
Future.successful(
BadRequest(Json.obj("message" -> s"invalid PowerPlantConfig $errors"))
)
},
success => { // fails here!!
dbService.newPowerPlant(toPowerPlantRow(success)).recover {
case NonFatal(ex) =>
Future.successful { UnprocessableEntity(
Json.obj("message" -> s"Could not create new PowerPlant because of ${ex.getMessage}")
) }
}
Future.successful { Ok("") }
}
)
}
這就是我認為的原因:
Controller.scala:103: a type was inferred to be `Any`; this may indicate a programming error.
[error] success => {
[error] ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 16 s, completed Aug 21, 2017 9:46:30 AM
關於為什么會發生此錯誤的任何想法? 我確定它與編譯器有關,因為我的控制器中有類似的代碼可以編譯!
您在"-Xfatal-warnings"
有"-Xfatal-warnings"
。 這使得編譯器拋出編譯錯誤,在正常情況下,這只是警告。 為了對此進行檢查,我評論了"-Xfatal-warnings"
。 然后sbt clean compile
給出以下內容:
alex@POSITRON /ssd2/projects/PowerPlantProblem/plant-simulator $ sbt clean compile
[info] Loading project definition from /ssd2/projects/PowerPlantProblem/plant-simulator/project
[info] Updating {file:/ssd2/projects/PowerPlantProblem/plant-simulator/project/}plant-simulator-build...
Waiting for lock on /home/alex/.ivy2/.sbt.ivy.lock to be available...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Set current project to plant-simulator (in build file:/ssd2/projects/PowerPlantProblem/plant-simulator/)
[success] Total time: 0 s, completed Aug 21, 2017 3:39:57 PM
[info] Updating {file:/ssd2/projects/PowerPlantProblem/plant-simulator/}root...
[info] Resolving jline#jline;2.14.3 ...
[info] Done updating.
[info] Compiling 31 Scala sources and 2 Java sources to /ssd2/projects/PowerPlantProblem/plant-simulator/target/scala-2.11/classes...
[warn] /ssd2/projects/PowerPlantProblem/plant-simulator/app/com/inland24/plantsim/controllers/PowerPlantController.scala:102: a type was inferred to be `Any`; this may indicate a programming error.
[warn] case Some(row) => dbService.newPowerPlant(row) recoverWith{
[warn] ^
[warn] one warning found
[success] Total time: 23 s, completed Aug 21, 2017 3:40:20 PM
alex@POSITRON /ssd2/projects/PowerPlantProblem/plant-simulator $
這意味着我的建議是正確的。 因此,您要么禁用該"-Xfatal-warnings"
要么使代碼滿足它帶來的更嚴格的要求。
現在,為了了解警告本身,請看一下recoverWith
方法的簽名:
def recoverWith[U >: T](pf: PartialFunction[Throwable, Future[U]])(implicit executor: ExecutionContext): Future[U]
在您的情況下, T
為Int
。 因此, Int
和Future[Result]
任何共同祖先當然是Any
。 只需插入一個Int
值,就可以使用"-Xfatal-warnings"
使它可編譯:
case Some(row) => dbService.newPowerPlant(row) recoverWith{
case ex: Exception => Future.successful{
UnprocessableEntity(
Json.obj("message" -> s"Could not create new PowerPlant because of ${ex.getMessage}")
)
5
}
}
該警告在這里是有意義的,因為代碼不干凈:您正在嘗試通過返回UnprocessableEntity
HTTP狀態(實際上沒有任何意義)來恢復向DB中插入行的問題(例如,DB服務器已關閉)。之后,您可以通過Future.successful { Ok("") }
覆蓋此意圖。
希望這可以幫助。
亞歷山大·阿倫達 ( Alexander Arendar)的暗示
我做了以下事情來解決這個問題:
def createNewPowerPlant = Action.async(parse.tolerantJson) { request =>
request.body.validate[PowerPlantConfig].fold(
errors => {
Future.successful(
BadRequest(Json.obj("message" -> s"invalid PowerPlantConfig $errors"))
)
},
success => {
toPowerPlantRow(success) match {
case None => Future.successful(
BadRequest(Json.obj("message" -> s"invalid PowerPlantConfig ")) // TODO: fix errors
)
case Some(row) =>
dbService.newPowerPlant(row).materialize.map {
case Success(insertedRecordId) =>
Ok("TODO: Send a Success JSON back with the id of the newly inserted record")
case Failure(ex) =>
UnprocessableEntity(
Json.obj("message" -> s"Could not create new PowerPlant because of ${ex.getMessage}")
)
}
}
}
)
}
注意,我正在使用Monix庫中的實現FutureExtensions方法!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.