Sunday, February 8, 2009

F# - Exceptions

#light

/// Standard exception and rethrow
try
    1/0
with
    | :? System.DivideByZeroException as exc ->
            printfn "1/0: %s" exc.Message
            1
    | _ -> rethrow()
            
    
/// Raise exception            
try
    raise (new System.Exception("Generic error"))
with
    | _ as exc -> printfn "Error: %s" exc.Message
    
/// F# exception
try
    failwith "F# error"
with
    | _ as exc -> 
        printfn "Error: %s" exc.Message
        printfn "Exception type: %O" (exc.GetType())

/// Finally
try
    failwith "Finally test"
finally
    printfn ">>Finally"
1/0: Attempted to divide by zero.
Error: Generic error
Error: F# error
Exception type: Microsoft.FSharp.Core.FailureException

Unhandled Exception: Microsoft.FSharp.Core.FailureException: Finally test
   at Microsoft.FSharp.Core.Operators.failwith[T](String message)
   at <StartupCode$Tupples>.$Program._main() in C:\Users\XXXXX\Documents\Visual
Studio 2008\Projects\XXXXX\Program.fs:line 29
>>Finally

Standard .NET exceptions can be handled by try … with expression. | is a pattern matching. :? is a type test, here against System.DivideByZeroException .NET exception.  as exc means exc is a variable that stores the exception (just like in C#). rethrow() rethrows the exception, like throw() in C#.

raise can raise an exception. | _ means pattern matching for any kind of exception.

F# exception can also be thrown. F# uses Microsoft.FSharp.Core.FailureException as its base exception type.

There is a finally block as well, just like in C#, to execute code after try block independently from try block results. Unfortunately with and finally can’t be combined.