I think you may benefit from using Option (http://danielwestheide.com/blog/2012/12/19/the-neophytes-guide-to-scala-part-5-the-option-type.html) and the Try object (http://danielwestheide.com/blog/2012/12/26/the-neophytes-guide-to-scala-part-6-error-handling-with-try.html)
What you are doing here is stopping all work when an error happens (ie you throw to outside the map) a better option is to isolate the failure and return some object that we can filer out. Below is a quick implementation I made
package csv
import play.api.libs.json.{JsObject, Json}
import scala.io.Source
import scala.util.Try
object CsvParser extends App {
//Because a bad row can either != 4 columns or the age can not be a int we want to return an option that will be ignored by our caller
def toTuple(array : Array[String]): Option[(String, String, String, Int)] = {
array match {
//if our array has exactly 4 columns
case Array(name, media, gender, age) => Try((name, media, gender, age.toInt)).toOption
// any other array size will be ignored
case _ => None
}
}
def toJson(line: String): Option[JsObject] = {
val cols = line.split(",").map(_.trim)
toTuple(cols) match {
case Some((name: String, media: String, gender: String, age: Int)) => Some(Json.obj("Name" -> name, "Media" -> media, "Gender" -> gender, "Age" -> age))
case _ => None
}
}
def parseFile(file: String): List[JsObject] = {
val bufferedSource = Source.fromFile(file)
try { bufferedSource.getLines().map(toJson).toList.flatten } finally { bufferedSource.close() }
}
parseFile("my/csv/file/path")
}
The above code will ignore any rows where there not exactly 4 columns. It will also contain the NumberFormatException from .toInt.
The idea is to isolate the failure and pass back some type that the caller can either work with when the row was parsed...or ignore when a failure happened.