You get an error, because of this line:
(mFile, data, caseID) = readSinglePair(idCase, mFolder, bName)
Here, readSinglePair returns an Option[(File, DataType1, String)]. But writing it this way, Scala expects the right-hand side of the = to be just the tuple, not wrapped in an Option. Handling errors with Option takes some getting used to, because things that can fail don’t have the same type any longer as things that can’t (which is good. When using nulls, you can’t see from a method’s signature, that it can fail and return null).
If you would want to only keep the good cases, you could replace = with <- here, which would then use the map function on option, like @cbley explained. map only does something, if there is a value in the Option, i.e. if it is a Some, and otherwise just returns None again, which when combined with a for that starts with a list is interpreted as an empty sequence.
But if I understand you correctly, your function should return a second sequence of all ids of failed cases too, correct?
In that case, you’ll probably want an Either instead of Option in the readSetOfData method. An Option is normally used, when there is only one way something can fail or you aren’t interested in how it failed (e.g. if in your readSinglePair you don’t care which exception occurred, you could keep Option).
An Either is similar to an Option, except that its error case can contain a value, it is either a Right (analogous to Some) or a Left (analogous to None, but containing a value). In your case, a Left would contain the id of a failed case.
As you already have a method that returns an Option for a single file, you can use the Option's conversion method toRight:
for {
idCase <- caseIDsList
} yield readSinglePair(idCase, mFolder, bName).toRight(idCase)
If readSinglePair returns a Some, toRight converts it to a Right with the same contents. Otherwise, it returns a Left containing the given parameter, in this case its id. This for would then return a List[Either[String, (File, DataType1, String)]].
Now, as you want a separat validCaseList and invalidCaseList, you’d have to split this again, but there is a better way. List provides a method, that for each element runs a given function returning an Either and sorts the result into two lists: partitionMap.
With that, the method would look like this:
def readSetOfData(caseIDsList: List[String], bName: String, mFolder: String)
: (List[String], List[(File, DataType1, String)]) =
caseIDsList.partitionMap(
idCase => readSinglePair(idCase, mFolder, bName).toRight(idCase)
)
Note that it now returns a tuple of two lists, one with the failed ids and one with the successful results:
It runs readSinglePair for each id in the input list. If it fails, the toRight converts it to a Left(idCase) and it ends up in the first resulting list, if it works, the toRight keeps the contents of the Option and it ends up in the second list.