如何重构此scala代码?

时间:2018-02-17 17:06:30

标签: scala playframework refactoring

我希望将这些代码重构为更具可读性和更好的代码。我知道在Scala中通常有很好的处理方式,但对我来说它有点乱(BTW我在代码中使用Play库)。这是我的代码片段:

class HomeController @Inject()
  (cc: ControllerComponents)
  (implicit val config: Configuration)
  extends AbstractController(cc) {

  def removeIdElement(uid: String) =
    HAction(uid, "AuthEvent", 1, "login", parse.text).async {
      implicit request: Request[String] =>
        val promise = Promise[Result]()
        Future {
          val removeId = request.body.toLong
          println(s"remove id $removeId")

          promise completeWith {
            idElementsDAO.remove(removeId, uid.toLong) map {
              _ => Ok("")
            } recover {
              case t: Throwable =>
                val errorMessage: String = getMessageFromThrowable(t)
                println("remove id element failure " + errorMessage)
                BadRequest(errorMessage)
            }
          }
        } recover {
          case t: Throwable =>
            val errorMessage: String = getMessageFromThrowable(t)
            println("remove id element failure " + errorMessage)
            promise.success(BadRequest(errorMessage))
        }
        promise.future
    }
}

2 个答案:

答案 0 :(得分:2)

以下是您的代码的简单版本:

class HomeController @Inject()(cc: ControllerComponents)(implicit val config: Configuration)
  extends AbstractController(cc) {

  def removeIdElement(uid: String) = HAction(uid, "AuthEvent", 1, "login", parse.text).async {
    implicit request: Request[String] =>

    Future {
      val removeId = request.body.toLong
      println(s"Removing id $removeId")
      removeId
    }.flatMap(id => idElementsDAO.remove(id, uid.toLong))
     .map(_ => Ok(""))
     .recover {
       case t: Throwable =>
         val errorMessage = getMessageFromThrowable(t)
         println(s"Removing id element failed: ${errorMessage}")
         BadRequest(errorMessage)
     }
  }
}

在上面的代码中,不需要Promise,并且不会重复recover组合子。

答案 1 :(得分:2)

假设idElementsDAO.remove返回Future,这可能更具惯用性:

def removeIdElement(uid: String) =
  HAction(uid, "AuthEvent", 1, "login", parse.text).async {implicit request =>
    val removeId = request.body.toLong
    println(s"remove id $removeId")

    idElementsDAO.remove(removeId, uid.toLong)
      .map(_ => NoContent) // probably more correct than `Ok("")`
      .recover {
        case t: Throwable =>
          val errorMessage: String = getMessageFromThrowable(t)
          println("remove id element failure " + errorMessage)
          BadRequest(errorMessage)
      }
  }

无需Promise或致电Future {...}Future.apply)。

请注意,直接将任何 Throwable的基本错误直接传递给http客户端(浏览器?)可能不是最好的主意。

如果您将通用错误处理代码添加到记录错误并向前端发送通用消息的全局错误处理程序(用于意外错误),那么您可以将其写为更清晰,如下所示:

def removeIdElement(uid: String) =
  HAction(uid, "AuthEvent", 1, "login", parse.text).async {implicit request =>
    val removeId = request.body.toLong
    println(s"remove id $removeId")

    for {
      _ <- idElementsDAO.remove(removeId, uid.toLong)
    } yield NoContent
  }

https://www.playframework.com/documentation/2.6.x/ScalaErrorHandling

相关问题