scala - 如何改进 "nested Try.. match "的代码?

标签 scala try-catch

在我的 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/

相关文章:

scala - 为什么 Scala 在分配给 val 时需要部分应用柯里化(Currying)函数?

postgresql - 如何配置使用 Postgresql Play JDBC?

java - 验证文本输入时如何避免 try-catch

sql-server - 忽略触发器中的错误

java - 用于 Java 和 Scala 开发的 Maven 替代品

scala - Go 与 Scala 的实时网络应用

javascript - 找不到原始元素时,如何单击另一个元素?

c# - C# 错误处理练习中的 throw 关键字负责什么

java - 在 try catch 中处理两个不同的连接关闭

java - 如何使用带有IP地址的rest客户端连接到elasticsearch服务器