加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

如何处理一个playframework异常2异步块(scala)

发布时间:2020-12-16 19:07:48 所属栏目:安全 来源:网络整理
导读:我的控制器动作代码如下所示: def addIngredient() = Action { implicit request = val boundForm = ingredientForm.bindFromRequest boundForm.fold( formWithErrors = BadRequest(views.html.Admin.index(formWithErrors)),value = { Async { val created
我的控制器动作代码如下所示:

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,并且在我所拥有的日志中:

play – Waiting for a promise,but got an error: Ingredient with name
‘test’ already exists. services.ValidationException: Ingredient with name
‘test’ already exists.

两个问题:

>从我的服务返回这个异常是一个坏主意,是否有更好/更多的scala方式来处理这种情况?
>如何捕获异常?

解决方法

我会说纯粹的功能方式是使用可以保存有效和错误状态的类型.

为此,您可以使用Validation形式的scalaz

但是如果不需要比scalaz更多的东西(你会^^),你可以使用一个非常简单的东西,使用Promise [Either [String,Ingredient]]作为结果,并在Async块中使用它的fold方法.也就是说,当兑换兑换承诺并折叠所兑换的地图时,转换价值.

好点=>无异常=>每一件事情都是打字检查:-)

编辑

它可能需要更多的信息,这里有两个选项:try catch,感谢@kheraud)和Either.没有把验证,如果需要的话问我.
????对象应用程序扩展Controller {

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

      }

  }

}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读