在我的 Scala 代码中,我有一些嵌套的 Try() match {}
,看起来很丑:
import scala.util._
Try(convertJsonToObject[User]) match {
case Success(userJsonObj) =>
Try(saveToDb(userJsonObj.id)) match {
case Success(user) => Created("User saved")
case _ => InternalServerError("database error")
}
case _ => BadRequest("bad input")
}
有没有更好的方法来编写这样的代码?
最佳答案
有很多方法可以解决这个问题。我给你一种可能。考虑一下你的代码的这个清理版本:
trait Result
case class BadRequest(message:String) extends Result
case class InternalServerError(message:String) extends Result
case class Created(message:String) extends Result
def processRequest(json:String):Result = {
val result =
for{
user <- Try(parseJson(json))
savedUser <- Try(saveToDb(user))
} yield Created("saved")
result.recover{
case jp:JsonParsingException => BadRequest(jp.getMessage)
case other => InternalServerError(other.getMessage)
}.get
}
def parseJson(json:String):User = ...
def saveToDb(user:User):User = ...
这段代码的警告是,它假设您可以通过每个可能产生的异常来区分 json 解析失败和 db 失败。不过,这不是一个糟糕的假设。这段代码非常类似于 java try/catch 块,它捕获不同的异常类型并根据捕获这些不同的类型返回不同的结果。
这种方法的另一个好处是,您可以为各种可能的异常定义一个标准的恢复部分函数,并在整个 Controller 中使用它(我假设这段代码是这样)以消除重复代码。像这样的东西:
object ExceptionHandling{
val StandardRecovery:PartialFunction[Throwable,Result] = {
case jp:JsonParsingException => BadRequest(jp.getMessage)
case sql:SQLException => InternalServerError(sql.getMessage)
case other => InternalServerError(other.getMessage)
}
}
然后在您的 Controller 中:
import ExceptionHandling._
result.recover(StandardRecovery).get
关于scala - 如何改进 "nested Try.. match "的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22927507/