What is the best way of handling exceptions while iterating over a loop in Scala?
For instance, if I had a convert()
method that could throw an exception, I'd like to catch that exception, log it, and keep iterating. Is there a "scala" way to do this?
Ideally, I'd like something like...
val points: Seq[Point] = ...
val convertedPoints: Seq[ConvertedPoint] = points.map(
p => {
try { p.convert() }
catch { case ex: Exception => logger.error("Could not convert", ex) }
})
You can't do the above code since it's not a direct mapping from one list to the other (you get back Seq[Any]
as opposed to Seq[ConvertedPoint]
).
Interesting that I had a lot of trouble explaining the advantages of using scala.util.control.Exception
over try
/catch
, and then I start to see questions that make perfect examples out of them.
Here:
import scala.util.control.Exception._
List(1, 23, 5, 2, 0, 3, 2) flatMap (x => catching(classOf[Exception]) opt (10 / x))
Your own code would look like this:
val points: Seq[Point] = ...
val convertedPoints: Seq[ConvertedPoint] = points.flatMap(
p => handling(classOf[Exception]) by { ex =>
logger.error("Could not convert", ex); None
} apply Some(p.convert)
)
Or, if you refactor it:
val exceptionLogger = handling(classOf[Exception]) by { ex =>
logger.error("Could not convert", ex); None
}
val convertedPoints: Seq[ConvertedPoint] = points.flatMap(p => exceptionLogger(Some(p.convert)))