scala - 两个异常 "at the same time",处理这种情况的正确方法是什么?

标签 scala exception try-catch

我遇到了需要调用 foo 的情况方法,如果失败调用bar方法,然后重新抛出原始异常(包装)。

我的问题是bar方法也可能失败,其异常信息也很重要。

当我创建一个新的异常时,只有一个原因,而我有两个原因。我可以创建类似 class MyException(cause1, cause2) extends RuntimeException(cause1) 的东西但是cause2将超出异常所具有的标准机制(堆栈跟踪等)。

有没有更好的方法来处理这种情况?

以下代码是一个简化的示例。

// I can't change this code
def foo:String = throw new FooException("foo method fails")
def bar:String = throw new BarException("bar method fails")

// my code
try {
  foo
} catch {
  case error1:FooException =>
    try {
      // if foo fails, I want to call bar
      bar
      throw new MyException("my exception", error1)
    } catch {
      case error2:BarException =>
        // but bar could fail too
        throw new MyException("my exception", ???)
        // if my cause is error1, I lost error2 information (message and stack)
        // if my cause is error2, I lost error1 information (message and stack)
    }
}

提前谢谢您。

最佳答案

您可以将 MyException throwable 与一个或两个“抑制”异常打包在一起。

val myEx = new MyException("my exception")
myEx.addSuppressed(error1)
myEx.addSuppressed(error2)
throw myEx

然后由捕获代码来解压它。

case err : MyException =>
  val arr :Array[Throwable] = err.getSuppressed
  // arr contains all the "suppressed" exceptions that were added,
  // stack traces and all

不过,可以说最好是表达类型系统中错误的可能性,而不是将其留给(可能不存在的)捕获代码来执行正确的操作。

import util.Try

val res :Either[List[Throwable],String] =
  Try(foo).fold(fErr =>
    Try(bar).fold(bErr => Left(fErr::bErr::Nil), _ => Left(fErr::Nil))
  , Right(_))

从那里您可以根据需要继续操作。

res match {
  case Right(s)  => println(s)  //foo result string
  case Left(lst) =>
    println(lst.map(_.getMessage()).mkString(",")) //foo method fails,bar method fails
    lst.foreach(_.printStackTrace())               //both stack traces
}

关于scala - 两个异常 "at the same time",处理这种情况的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52339385/

相关文章:

scala - 在scala中堆叠Monad Transformers

scala - 无法使用 Spark Structured Streaming 在 Parquet 文件中写入数据

c# - 使用事件而不是异常来实现错误处理

asp.net - Microsoft.VisualBasic.Financial.Rate 错误, "Cannot calculate rate using the arguments provided"

javascript - try..catch 没有捕捉到异步/等待错误

function - 自定义 scala 递归预防机制的改进

c# - 为什么 C# 不支持首次通过异常过滤?

python - 为什么我的 Python 异常没有被重新引发?

php - 尝试在 PHP 中捕获 - 我应该在 'try' block 中返回吗?

scala - 如何在 Scala 中弃用具有默认值的参数?