处理Play2.5 / scala控制器中的异常

时间:2016-10-25 04:51:15

标签: scala playframework playframework-2.5

我想捕获异常并重定向到以下代码中的自定义页面。但是,不会发现/看到异常。

def addItemWithParts(item: Item, parts: Seq[String]): Future[Int] = {
  ... // May throw exceptions
}

def handleAddItem = auth.SecuredAction.async { implicit request =>
  itemForm.bindFromRequest.fold(
    formWithErrors => {
      Future.successful(
        Redirect(controllers.www.routes.ItemController.startAddItem()).flashing(
          "error" -> "Bad item add input"
        )
      )
    },
    item => {
      for {
        ue <- usersService.findUserEntryByEmail(request.identity.email)
      } yield ue match {
        case Some(ue) =>
          val itemObj = Item(item.name, item.description, ue.companyId)
          val xx = itemsService.addItemWithParts(itemObj, Seq(item.parts)) <-- want to catch exception thrown by this function
          /*
           * COMMENTED CODE PRINTS EXCEPTION ON CONSOLE, BUT DONT KNOW HOW TO REDIRECT/OK...
          xx onComplete {
            case Success(x) => {
              println("Added ITEM: " + x)
              Redirect(controllers.www.routes.Dashboard.dashboard)
            }
            case Failure(exp) => {
              println("Exception while adding ITEM: " + exp)
              Ok("Got exception: " + exp)
            }
          }
          */
          Redirect(controllers.www.routes.Dashboard.dashboard) // +++
        case None =>
          Ok("Bad")
      }
    }
  )
}

我以为我可以从onComplete成功而不是标记为&#34; +++&#34;的行进行Redirect();但是我得到了这个编译错误:

type mismatch;
[error]  found   : Unit
[error]  required: play.api.mvc.Result
[error]           case Some(ue) =>
[error]                         ^
[error] one error found

我检查了播放文档,它讨论了将onServerError添加到ErrorHandler(集中),但我想知道我在这样做时缺少什么。

我还在学习Scala,我们非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

onComplete返回Unit。您只能使用onComplete执行副作用。

使用mapflatMap撰写和构建新计算。使用recoverrecoverWith来处理异常并返回异常内容。

这是你如何做到这一点

val result = 
for {
 ueOpt <- usersService.findUserEntryByEmail(request.identity.email)
 result <- ueOpt match {
            case Some(ue) =>

               val itemObj = Item(item.name, item.description, ue.companyId)
               val foo = itemsService.addItemWithParts(itemObj, Seq(item.parts))

              foo.map { value =>
                Redirect(controllers.www.routes.Dashboard.dashboard)
              }.recover { case th =>
                InternalServerError("bad things happen in life.")
              }

            case None => Future.successful(BadRequest("no item found"))
          }
} yield result

Future提供了mapflatMap等方法来构建具有当前未来结果的新计算。未来还提供recoverrecoverWith来构建当前未来抛出异常时的计算。

def bar: Future[Int] = ???

bar.map { intValue =>
  //doSomething
}.recover {
  case ex: SQLException => //return some value
  case _ => //ignore other exceptions and return default value
}