我希望将这些代码重构为更具可读性和更好的代码。我知道在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
}
}
答案 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