簡體   English   中英

具有部分函數的Scala奇怪錯誤

[英]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]

在您的情況下, TInt 因此, IntFuture[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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM