如何收集错误是scala,然后将所有错误汇总在一起

时间:2018-08-15 20:52:27

标签: scala error-handling jvm

这是我的职能:

val timeComparator: Function[String, String] = new Function[String, String] {
  def something() {
  //Does some time calculation
  }

  override def apply(element: CharSequence, element1: CharSequence): Any = {
     if (something(parameter1, parameter2)) {
          Left(sys.error("Does not work"))
     } 
  }
}

val callingFunction: Unit = {
  timeComparator(parameter1, parameter2)
}


trait Function[A, B, C] {
  def apply(element : String, element1 :String): Any
}

现在,此代码在每次有新数据可用时都运行,如果失败,则应该引发错误。我如何收集这些错误,而不是连续处理数据并抛出错误,我希望它一起处理所有数据(而不是抛出错误),然后最后抛出类似“这里是50个数据点的列表”的信息失败”,本质上是累积错误,而不是在创建错误时就将它们抛出。我是Scala的新手,对Scala中的错误处理不太熟悉。

1 个答案:

答案 0 :(得分:1)

您无法收集多个错误,然后“全部抛出”。您可以做的是收集Throwable包裹在Try.Failure()中的包裹。

我通常会尝试通过将其插入到您的用例中来演示该概念,但是您的“伪代码”没有任何意义,也无助于阐明您要实现的目标。因此,我将整理一个简单的示例,希望您能够将其转移到您的实际情况中。

这是一种可以引发两种不同类型错误的方法。

def calc(in :Int) :Int =
  if (4/in < 1)                 //can throw ArithmeticException
    throw new Error("too big")  //can throw java.lang.Error
  else
    4 * in

让我们进行更改。让我们返回错误,而不是抛出错误。

import util.Try

def calc(in :Int) :Try[Int] = Try{
  if (4/in < 1)                 //can throw ArithmeticException
    throw new Error("too big")  //can throw java.lang.Error
  else
    4 * in
}

现在让我们提供一些数据。

val data = 0 to 5
val results = data.map(calc)
//results: Seq[Try[Int]] = Seq(Failure(java.lang.ArithmeticException: / by zero)
//                           , Success(4), Success(8), Success(12), Success(16)
//                           , Failure(java.lang.Error: too big))

从这里我们可以区分好与坏,并采取相应的行动。

val (good,bad) = results.partition(_.isSuccess)
report_these_numbers(good.map(_.get))  //Seq(4, 8, 12, 16)
log_these_errors(bad)   //Seq(Failure(java.lang.ArithmeticException: / by zero)
                        //  , Failure(java.lang.Error: too big))