在 Play2.5/scala 控制器中处理异常
Handle exception in Play2.5/scala controller
我想在以下代码中捕获异常并重定向到自定义页面。但是,例外情况不是 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")
}
}
)
}
我以为我可以从 onComplete success 而不是在标记为“+++”的行执行 Redirect() 但我收到此编译错误:
type mismatch;
[error] found : Unit
[error] required: play.api.mvc.Result
[error] case Some(ue) =>
[error] ^
[error] one error found
我查看了 play 文档,它讨论了将 onServerError 添加到 ErrorHandler(集中式),但我想知道我在这样做时遗漏了什么。
我还在学习 Scala,非常感谢任何帮助。
onComplete
returns Unit
。您只能使用 onComplete
.
进行副作用操作
使用 map
、flatMap
来组合和构建新的计算。使用 recover
和 recoverWith
处理异常,return 处理异常。
这里是你如何做到这一点
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
提供了像 map
、flatMap
这样的方法来用当前未来的结果构建新的计算。此外,future 还提供 recover
和 recoverWith
来在当前 future 抛出异常时构建计算。
def bar: Future[Int] = ???
bar.map { intValue =>
//doSomething
}.recover {
case ex: SQLException => //return some value
case _ => //ignore other exceptions and return default value
}
我想在以下代码中捕获异常并重定向到自定义页面。但是,例外情况不是 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")
}
}
)
}
我以为我可以从 onComplete success 而不是在标记为“+++”的行执行 Redirect() 但我收到此编译错误:
type mismatch;
[error] found : Unit
[error] required: play.api.mvc.Result
[error] case Some(ue) =>
[error] ^
[error] one error found
我查看了 play 文档,它讨论了将 onServerError 添加到 ErrorHandler(集中式),但我想知道我在这样做时遗漏了什么。
我还在学习 Scala,非常感谢任何帮助。
onComplete
returns Unit
。您只能使用 onComplete
.
使用 map
、flatMap
来组合和构建新的计算。使用 recover
和 recoverWith
处理异常,return 处理异常。
这里是你如何做到这一点
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
提供了像 map
、flatMap
这样的方法来用当前未来的结果构建新的计算。此外,future 还提供 recover
和 recoverWith
来在当前 future 抛出异常时构建计算。
def bar: Future[Int] = ???
bar.map { intValue =>
//doSomething
}.recover {
case ex: SQLException => //return some value
case _ => //ignore other exceptions and return default value
}