I am trying to write a F# function that reads a CSV file and returns its lines as a sequence of strings that can be further processed in a pipelined expression. The function should handle all exceptions that can arise when opening and reading a file. This is what I came up with so far:
// takes a filename and returns a sequence of strings
// returns empty sequence in case file could not be opened
let readFile (f : string) =
try
seq {
use r = new StreamReader(f) // if this throws, exception is not caught below
while not r.EndOfStream do
yield reader.ReadLine() // same here
}
with ex
| ex when (ex :? Exception) ->
printfn "Exception: %s" ex.Message
Seq.empty
The problem here is that the exceptions that could be thrown by StreamReader() and ReadLine() are not caught in the exception handler but instead are left uncaught and lead to program termination. Also, there seems to be no way of trying to catch exceptions inside the seq {} sequence expression. Right now I cannot think of any other way to design such a function than reading the whole file into an intermediate collection like a list or an array beforehand and then returning this collection as a sequence to the callers, thereby loosing all the benefits of lazy evaluation.
Has anybody got a better idea ?