【问题标题】:Catching exception in Play for Scala method在 Play for Scala 方法中捕获异常
【发布时间】:2017-07-06 02:29:26
【问题描述】:

这个 Play for Scala 方法(应该返回 Future[play.api.mvc.Result])调用另一个方法 run,这是一个可能引发异常的未来。如果run 没有抛出异常,那么该方法应该返回一个ret 等于0 的Json。如果run 确实引发了异常,那么该方法应该返回一个具有ret 等于1 的Json。

问题是OnComplete 抛出编译错误:

类型不匹配;找到:所需单位: scala.concurrent.Future[play.api.mvc.Result]

如何解决这个问题?

   def test (req:Int) : Future[play.api.mvc.Result] = {

       val future = run(req)  
       future.map {
          result => 
               val json = JsObject(Seq(
                          "rs" -> Json.toJson(result),
                          "ret" -> JsString("0")
                      ))
               Ok(json)
           }

       future.onComplete { // <-- compilation error
              case Success(_) => // do nothing
              case Failure(ex) => {
                  val json = JsObject(Seq(
                         "msg" -> JsString(ex.getMessage),
                         "ret" -> JsString("1")
                    ))
                  Ok(json)
              }
            }

   }

【问题讨论】:

    标签: scala playframework playframework-2.0


    【解决方案1】:

    在 Scala 中,方法中最后一个表达式的结果成为方法的返回值。 future.onComplete 返回一个 Unit,这使得函数体“返回”一个 Unit。

    你真正想要的是recover

    def test (req:Int) : Future[play.api.mvc.Result] = {
        run(req)
            .map(result => Ok(JsObject("rs" -> ..., "ret" -> 0)))
            .recover({ case NonFatal(ex) => 
                Ok(JsObject(Seq("msg" -> ..., "ret" -> 1))
            })
    }
    

    另外,请注意map 返回新的未来,因此在您的示例中,您将onComplete 回调附加到run 返回的未来,这 包括该json 处理;所以map 调用中的失败不会被onComplete Failure(ex) 分支捕获。如您所见,我已在上面的 sn-p 中更正了这一点。

    【讨论】:

    • recover 采用一个采用Throwable 而不是Failure 的函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-12
    • 2021-04-13
    • 2021-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多