【问题标题】:Scala Try/Future, wrapping the exception in case of failureScala Try/Future,在失败的情况下包装异常
【发布时间】:2013-12-13 15:34:30
【问题描述】:

假设我有一个方法def doSomething: String,如果出现问题,它可以引发DoSomethingException

如果我写Try(doSomething),有没有一种简单的方法来映射异常而不恢复它?

基本上,我希望成为由DoSomethingException 引起的BusinessException 失败。

我知道执行此操作的代码非常简单,但是没有任何内置运算符可以执行此操作吗?这似乎是一个很常见的操作,但我在 API 中找不到任何东西。

【问题讨论】:

  • 为什么你不想从你的doSomething抛出这个异常

标签: scala try-catch functor


【解决方案1】:

带恢复:

val c = scala.util.Try(doSomething).recover { 
    case e: DoSomethingException => throw new BusinessException
}

【讨论】:

  • 这似乎是一个不错的主意,但会产生编译问题,因为未推断出部分函数返回类型
  • 它对我有用,如果编译器可以进行推理,它似乎取决于上下文。在任何情况下,您都可以使其明确,但此解决方案不存在逻辑或类型问题。
  • @SebastienLorber collect 可能会产生问题,但这里的左类型无论如何都是 Throwable
【解决方案2】:

您可以使用transform

val t = Failure(new DoSomethingException)
val bt = t.transform(s => Success(s), e => Failure(new BusinessException))

【讨论】:

  • 谢谢,效果很好。我本来希望某些东西只处理失败而不是两者,比如 mapFailure 或其他东西
【解决方案3】:

你也可以使用recoverWith:

Try {
    doSomething
} recoverWith { 
    case e: DoSomethingException => Failure(new BusinessException)
}

【讨论】:

    【解决方案4】:

    您也可以尝试使用 PartialFunction 进行匹配(如果没有失败,则打开该值):

    Try(doSomething) match {
        case Success(result) => result
        case Failure(throwable) => new BusinessException(throwable)
      }
    

    【讨论】:

    • match,而不是map。无法编辑帖子,因为编辑长度太小。
    • @Shannon 你为什么不喜欢地图?
    • 它无法编译。如果doSomethingAny,你可以编译它,但是你得到的是Failure(scala.MatchError)match 既编译又做你想做的事。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    • 2014-04-12
    • 2013-08-17
    • 1970-01-01
    • 1970-01-01
    • 2019-11-19
    相关资源
    最近更新 更多