#scala #playframework #playframework-2.5
#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")
}
}
)
}
Я думал, что смогу выполнить Redirect() из onComplete success вместо строки с пометкой » «, но я получаю эту ошибку компиляции:
type mismatch;
[error] found : Unit
[error] required: play.api.mvc.Result
[error] case Some(ue) =>
[error] ^
[error] one error found
Я проверил документацию play, там говорится о добавлении onServerError в ErrorHandler (централизованный), но я хочу знать, чего мне не хватает при выполнении этого таким образом.
Я все еще изучаю Scala, любая помощь высоко ценится.
Комментарии:
1. Используйте
map
для правильного случая иrecover
для исключения.
Ответ №1:
onComplete
ВОЗВРАТ Unit
. Вы можете выполнять только побочные операции, используя onComplete
.
Используйте map
, flatMap
для составления и построения новых вычислений. Используйте recover
и recoverWith
для обработки исключений и возврата чего-либо в исключениях.
вот как вы можете это сделать
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
}