例如
def shouldThrow:String = throw new RuntimeException("exception1")
def shouldThrowButWithContextDetails(detail:String):Try[String] = {
val ex = Try{shouldThrow}
if(ex.isFailure)
Failure(new RuntimeException(s"Error in context: $detail",ex.failed.get))
else
ex
}
shouldThrowButWithContextDetails("detail1")
//should throw new RuntimeException(s"Error in context: detail1",and the cause))
在scala中做这样的事情是否有意义?
答案 0 :(得分:1)
不是使用Exception
对Try
中的所有内容进行编码,而是最好使用Either
(更好的是,Scalaz \/
),然后你可以在左侧(失败)方面拥有除例外之外的其他东西。您可以使用scala.util.control.Exception
来捕获Either
s中的例外:
import scala.util.control.Exception._
def shouldThrowButWithContextDetails(detail:String)
: Either[(Exception, String), String] = {
val ex: Either[Exception, String] = allCatch either shouldThrow
ex.left.map { failure => (failure, s"Error in context: $detail") }
}
然后Left
(失败)案例具有适当的类型(Execption, String)
,您可以以适当的方式处理,而不是试图在Exception
中走私额外的数据。
答案 1 :(得分:1)
到目前为止,我发现的最简单的方法是这种方法
def shouldThrowButWithContextDetails(detail:String):Try[String] =
Try{shouldThrow}.transform(
x=>Success(x),
f=>Failure(new RuntimeException(s"Error in context: $detail",f)))
答案 2 :(得分:1)
使用recoverWith是否合适?
def shouldThrowButWithContextDetails(detail:String):Try[String] =
Try{shouldThrow}.recoverWith{
case ex:Throable=> Failure(new RuntimeException(s"Error in context: $detail",ex))}
答案 3 :(得分:0)
将这样的上下文信息包装起来是完全正常的。
然而,如果意图是最终应该抛出异常,那么你就不需要坚持尝试。使用匹配来分离失败与成功相比要简单得多。这是我看到它最常用的方式:
def shouldThrowButWithContextDetails(detail:String): String = {
Try {shouldThrow} match {
case Success(s) => s
case Failure(e) =>
throw new RuntimeException(s"Error in context: $detail", e)
}
}