简体   繁体   English

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

[英]Handle exception in Play2.5/scala controller

I would like to catch exception and redirect to a custom page in the following code. 我想捕获异常并在以下代码中重定向到自定义页面。 However, exceptions are not caught/seen. 但是,未捕获/看到异常。

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")
      }
    }
  )
}

I thought I can do Redirect() from onComplete success instead of at line marked "+++" but I get this compilation error: 我以为我可以从onComplete成功执行Redirect()而不是标记为“ +++”的行,但是出现此编译错误:

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

I checked play documentation, it talks about adding onServerError to ErrorHandler (centralized) but I want to know what I am missing in doing it this way. 我查看了播放文档,其中谈到了将onServerError添加到ErrorHandler(集中式),但是我想知道这样做时所缺少的内容。

I am still learning Scala, any help is deeply appreciated. 我仍在学习Scala,我们将不胜感激。

onComplete returns Unit . onComplete返回Unit You can do only side effecting operations using onComplete . 您只能使用onComplete副作用操作。

Use map , flatMap for composing and building new computations. 使用mapflatMap组成和构建新的计算。 Use recover and recoverWith to handle exceptions and return something on exceptions. 使用recoverrecoverWith处理异常并在异常上返回一些信息。

here is how you can do this 这是你怎么做的

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 provides methods like map , flatMap to build new computations with result of the current future. Future提供诸如mapflatMap类的方法,以根据当前future的结果构建新的计算。 Also future provides recover and recoverWith to build computations when current future throws exceptions. 当当前的将来抛出异常时,将来recoverWith提供recoverrecoverWith来构建计算。

def bar: Future[Int] = ???

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM