如何处理一个playframework异常2异步块(scala)
我的控制器动作代码如下所示:
def addIngredient() = Action { implicit request => val boundForm = ingredientForm.bindFromRequest boundForm.fold( formWithErrors => BadRequest(views.html.Admin.index(formWithErrors)),value => { Async { val created = Service.addIngredient(value.name,value.description) created map { ingredient => Redirect(routes.Admin.index()).flashing("success" -> "Ingredient '%s' added".format(ingredient.name)) } // TODO on exception do the following // BadRequest(views.html.Admin.index(boundForm.copy(errors = Seq(FormError("",ex.getMessage()))))) } }) } 我的Service.addIngredient(…)返回一个Promise [Ingredient],但也可以抛出一个自定义ValidationException.抛出此异常时,我想返回已注释的代码. 目前,该页面呈现为500,并且在我所拥有的日志中:
两个问题: >从我的服务返回这个异常是一个坏主意,是否有更好/更多的scala方式来处理这种情况? 解决方法
我会说纯粹的功能方式是使用可以保存有效和错误状态的类型.
为此,您可以使用Validation形式的scalaz 但是如果不需要比scalaz更多的东西(你会^^),你可以使用一个非常简单的东西,使用Promise [Either [String,Ingredient]]作为结果,并在Async块中使用它的fold方法.也就是说,当兑换兑换承诺并折叠所兑换的地图时,转换价值. 好点=>无异常=>每一件事情都是打字检查:-) 编辑 它可能需要更多的信息,这里有两个选项:try catch,感谢@kheraud)和Either.没有把验证,如果需要的话问我. def index = Action { Ok(views.html.index("Your new application is ready.")) } //Using Try Catch // What was missing was the wrapping of the BadRequest into a Promise since the Async // is requiring such result. That's done using Promise.pure def test1 = Async { try { val created = Promise.pure(new {val name:String = "myname"}) created map { stuff => Redirect(routes.Application.index()).flashing("success" -> "Stuff '%s' show".format(stuff.name)) } } catch { case _ => { Promise.pure(Redirect(routes.Application.index()).flashing("error" -> "an error occurred man")) } } } //Using Either (kind of Validation) // on the Left side => a success value with a name val success = Left(new {val name:String = "myname"}) // on the Right side the exception message (could be an Exception instance however => to keep the stack) val fail = Right("Bang bang!") // How to use that // I simulate your service using Promise.pure that wraps the Either result // so the return type of service should be Promise[Either[{val name:String},String]] in this exemple // Then while mapping (that is create a Promise around the convert content),we folds to create the right Result (Redirect in this case). // the good point => completely compiled time checked ! and no wrapping with pure for the error case. def test2(trySuccess:Boolean) = Async { val created = Promise.pure(if (trySuccess) success else fail) created map { stuff /* the either */ => stuff.fold( /*success case*/s => Redirect(routes.Application.index()).flashing("success" -> "Stuff '%s' show".format(s.name)),/*the error case*/f => Redirect(routes.Application.index()).flashing("error" -> f) ) } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |