I want to apply a function f
to each element of a List
and not stop at the first error but throw the last error (if any) only:
@annotation.tailrec
def tryAll[A](xs: List[A])(f: A => Unit): Unit = {
xs match {
case x :: xt =>
try {
f(x)
} finally {
tryAll(xt)(f)
}
case _ =>
}
}
But, the above code does not compile - it is complaining that this function is not tail recursive. Why not?
This solution iterates over all elements and produces (throws) the last error if any:
def tryAll[A](xs: List[A])(f: A => Unit): Unit = {
val res = xs.foldLeft(Option.empty[Throwable]) {
case (maybeThrowable, a) =>
Try(f(a)) match {
case Success(_) => maybeThrowable
case Failure(e) => Option(e)
}
}
res.foreach(throwable => throw throwable)
}