【问题标题】:Two exceptions "at the same time", what is the proper way to handle this situation?两个异常“同时”,处理这种情况的正确方法是什么?
【发布时间】:2019-02-19 16:54:31
【问题描述】:

我有一种情况需要调用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)
    }
}

提前谢谢你。

【问题讨论】:

  • 如果bar 成功了会发生什么?是否应该丢弃返回的 String 以支持抛出 foo 错误?调用bar 是否只是为了产生副作用?
  • 是的,bar 是插入数据库,在这种情况下,它的返回被丢弃

标签: scala exception-handling try-catch


【解决方案1】:

您可以将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
}

【讨论】:

  • 那么,您的建议是返回一个 Either 而不是抛出异常?
猜你喜欢
  • 1970-01-01
  • 2013-03-21
  • 1970-01-01
  • 1970-01-01
  • 2013-08-31
  • 1970-01-01
  • 2021-10-01
  • 2011-03-26
  • 1970-01-01
相关资源
最近更新 更多