【问题标题】:Handle exception in Play2.5/scala controller在 Play2.5/scala 控制器中处理异常
【发布时间】:2016-10-25 04:51:14
【问题描述】:

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

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 成功而不是在标记为“+++”的行中执行 Redirect(),但我收到此编译错误:

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

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

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

【问题讨论】:

  • 使用map 表示好的情况,recover 表示例外情况。

标签: scala playframework playframework-2.5


【解决方案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 等方法来使用当前未来的结果构建新的计算。 future 还提供 recoverrecoverWith 来在当前 future 抛出异常时构建计算。

def bar: Future[Int] = ???

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-04
    • 1970-01-01
    相关资源
    最近更新 更多