映射失败的 Future 的异常

Posted

技术标签:

【中文标题】映射失败的 Future 的异常【英文标题】:Map the Exception of a failed Future 【发布时间】:2013-08-17 12:52:17 【问题描述】:

在 scala 中,map Exception 的失败 Future 最干净的方法是什么?

说我有:

import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global

val f = Future  
  if(math.random < 0.5) 1 else throw new Exception("Oh no") 

如果 Future 使用 1 成功,我想保留它,但如果失败,我想将 Exception 更改为不同的 Exception

我能想到的最好的方法是转换,但这需要我为成功案例创建一个不必要的函数:

val f2 = f.transform(s => s, cause => new Exception("Something went wrong", cause))

没有mapFailure(PartialFunction[Throwable,Throwable])有什么原因吗?

【问题讨论】:

转换是正确的方法。不需要创建 s => s 函数,传入identity 干杯。我不知道identity 函数。我相信会有更多的时间派上用场。 【参考方案1】:

还有:

f recover  case cause => throw new Exception("Something went wrong", cause) 

从 Scala 2.12 开始,您可以:

f transform 
  case s @ Success(_) => s
  case Failure(cause) => Failure(new Exception("Something went wrong", cause))

f transform  _.transform(Success(_), cause => Failure(new Exception("Something went wrong", cause)))

【讨论】:

虽然这是一个非常清晰的语法,但我们仍然需要throw 新异常,而不是将Throwable 映射到Throwable。有没有一个组合器?【参考方案2】:

你可以试试recoverWith

f recoverWith
  case ex:Exception => Future.failed(new Exception("foo", ex))

【讨论】:

Future.failed 不在 ExecutionContext 上评估:scala-lang.org/api/current/#scala.concurrent.Future$ 见 failed @ViktorKlang,那我一定很困惑。我在查看impl.KeptPromise 类的onComplete 方法时做出了这个假设。在那里,有两条线val preparedEC = executor.prepare; (new CallbackRunnable(preparedEC, func)).executeWithValue(completedAs)。我认为这意味着即使我们给出了一个明确的值,它仍然由于某种原因正在打击执行者。这对我来说总是很奇怪,我想这实际上是因为我误读了它。感谢您的提醒。 感谢您的回答。我对使用recover/recoverWith 唯一的犹豫是,当我看到它时,我立即假设其意图是从失败中恢复并获得成功的结果。也许这只是我。即便如此,它们也是不错的选择,谢谢! @cmbaxter 我仍然不明白它是如何不命中 ExecutionContext 的。 @cmbaxter - 请你看看我的相关问题 - ***.com/questions/31173982/….

以上是关于映射失败的 Future 的异常的主要内容,如果未能解决你的问题,请参考以下文章

Java 集合快速失败异常

使用返回 Future 的函数映射 Stream

RestKit & Cocoapods:映射操作失败/没有找到任何可映射的值

添加ORDER BY时出现“SQL0802 - 数据映射错误的数据转换”异常

maven异常解决:编码GBK的不可映射字符

当我尝试反序列化对象列表时,杰克逊抛出错误映射异常