Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用什么惯用的scala方法向Try实例中包装的抛出异常添加更多细节_Scala_Exception Handling_Idioms - Fatal编程技术网

用什么惯用的scala方法向Try实例中包装的抛出异常添加更多细节

用什么惯用的scala方法向Try实例中包装的抛出异常添加更多细节,scala,exception-handling,idioms,Scala,Exception Handling,Idioms,比如说 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:

比如说

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中做这样的事情有意义吗?

与其用
Try
异常中编码所有内容,不如使用
(更好的是,Scalaz
\/
),然后在左侧(失败)可以有异常以外的其他内容。您可以使用
scala.util.control.Exception
捕获
中的异常:

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
(failure)案例有一个适当的类型
(Execption,String)
,您可以用适当的方式处理它,而不是试图在
异常中走私额外的数据

像这样包装上下文信息是完全正常的

但是,如果目的是最终抛出异常,则不需要继续尝试。使用匹配来区分失败和成功要简单得多。这是我看到的最常见的使用方式:

def shouldThrowButWithContextDetails(detail:String): String = {
    Try {shouldThrow} match {
        case Success(s) => s
        case Failure(e) =>
          throw new RuntimeException(s"Error in context: $detail", e)
    }
}

到目前为止,我发现的最简单的事情就是这种方法

def shouldThrowButWithContextDetails(detail:String):Try[String] =
  Try{shouldThrow}.transform(
    x=>Success(x),
    f=>Failure(new RuntimeException(s"Error in context: $detail",f)))

使用它好吗

def shouldThrowButWithContextDetails(detail:String):Try[String] = 
    Try{shouldThrow}.recoverWith{
        case ex:Throable=> Failure(new RuntimeException(s"Error in context: $detail",ex))}

现在我意识到我希望找到一个像def-tryInContext(context:=>Any)(block:=>tryBlock):Try[T]=???你会如何使用它?什么是Try或Try做不到的?我会像
def shouldThrowButWithContextDetails(detail:String):Try[String]=tryInContext(detail)(shouldThrow)
那样使用它。不断的尝试可以做任何必要的事情。我在寻找一种惯用的方法来做这件事。