During normal program's execution an exception may occur.
In case I'm aware of it and just want to ignore it — how do I achieve this in F#?
Here is my code, which compiles with a warning:
let sha = new SHA1CryptoServiceProvider()
let maxLength = 10000
let fileSign file =
let fs = File.OpenRead(file)
let mutable res = (0L, [|0uy|])
try
let flLen = fs.Length
let len = int (min (int64 maxLength) flLen)
// read 'len' bytes
let mutable pos = 0
while (pos < len) do
let chunk = fs.Read(buf, pos, len - pos)
pos <- pos + chunk
// get signature
let sign = sha.ComputeHash(buf, 0, len)
// store new result
res <- (flLen, sign)
with
| :? IOException as e -> e |> ignore
finally
if (fs <> null) then
fs.Dispose()
res
The warning is:error FS0010: Unexpected keyword 'finally' in binding. Expected incomplete structured construct at or before this point or other token.
The corresponding C# equivalent for what I want is:
FileStream fs = null;
try
{
fs = File.OpenRead(file);
// ... other stuff
}
catch
{
// I just do not specify anything
}
finally
{
if (fs != null)
fs.Dispose()
}
If I just omit the with
block in F#, the exception is not ignored.
There is no way to basically ignore a thrown exception. The best that you can do is to limit the standard you have to wrap the exception-throwing code in.
In this case, you want to catch NameError and specify a message. For all others, you want to specify another message. Let's say you want to ignore NameError, then you can just give continue or pass . Alternatively, you can also raise an exception.
You should not ignore Exceptions. You should handle them. If you want to make your test code simple, then add the try-catch block into your functions. The greatest way to ignore exceptions is to prevent them by proper coding.
If you are in a for loop and want to skip to the next iteration, use the continue keyword instead. If you only need to access a specific key and need to ignore the KeyError exception, use the dict. get() method.
try-with and try-finally are separate constructs in F#, so you need an extra 'try' to match the finally:
try
try
...
with e -> ...
finally
...
As Vitaliy points out, it's more idiomatic to use 'use' for finallys-that-dispose
use x = some-IDisposable-expr
...
See also
Docs about 'use': http://msdn.microsoft.com/en-us/library/dd233240(VS.100).aspx
Spec for 'use': http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/spec.html#_Toc245030850
try..with..finally is not supported in F#. As well as in OCaml. You should use use statement here:
try
use fs = ...
with....
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With