F Sharp Programming/Exception Handling

When a program encounters a problem or enters an invalid state, it will often respond by throwing an exception. Left to its own devices, an uncaught exception will crash an application. Programmers write exception handling code to rescue an application from an invalid state.

Try/With
Let's look at the following code: This code is syntactically valid, and it has the correct types. However, it can fail at run time if we give it a bad input:

This program outputs the following:

x = 7 y = monkeys! FormatException was unhandled. Input string was not in a correct format.

The string  does not represent a number, so the conversion fails with an exception. We can handle this exception using F#'s, a special kind of pattern matching construct:

This program outputs the following:

x = 7 y = monkeys! 7 + -2147483648 = -2147483641

It is, of course, wholly possible to catch multiple types of exceptions in a single  block. For example, according to the MSDN documentation, the  method will throw three types of exceptions:


 * Occurs when  is a null reference.


 * Occurs when  does not represent a numeric input.


 * Occurs when  represents number greater than or less than   or   (i.e. the number cannot be represented with a 32-bit signed integer).

We can catch all of these exceptions by adding additional match cases:

Its not necessary to have an exhaustive list of match cases on exception types, as the uncaught exception will simply move to the next method in the stack trace.

Raising Exceptions
The code above demonstrates how to recover from an invalid state. However, when designing F# libraries, its often useful to throw exceptions to notify users that the program encountered some kind of invalid input. There are several standard functions for raising exceptions:

For example:

Try/Finally
Normally, an exception will cause a function to exit immediately. However, a  block will always execute, even if the code throws an exception:

This program will output the following: - catchAllExceptions: try block tryWithFinallyExample: outer try block tryWithFinallyExample: inner try block Function executed successfully tryWithFinally: outer finally block - catchAllExceptions: try block tryWithFinallyExample: outer try block tryWithFinallyExample: inner try block tryWithFinallyExample: inner with block tryWithFinally: outer finally block catchAllExceptions: with block Exception message: Function executed with an error

Notice that our finally block executed in spite of the exception. Finally blocks are used most commonly to clean up resources, such as closing an open file handle or closing a database connection (even in the event of an exception, we do not want to leave file handles or database connections open):

Statement
Many objects in the .NET framework implement the System.IDisposable interface, which means the objects have a special method called  to guarantee deterministic cleanup of unmanaged resources. It's considered a best practice to call  on these types of objects as soon as they are no longer needed.

Traditionally, we'd use a  block in this fashion: However, this can be occasionally bulky and cumbersome, especially when dealing with many objects which implement the IDisposable interface. F# provides the keyword  as syntactic sugar for the pattern above. An equivalent version of the code above can be written as follows:

The scope of a  statement is identical to the scope of a   statement. F# will automatically call  on an object when the identifier goes out of scope.

Defining New Exceptions
F# allows us to easily define new types of exceptions using the  declaration. Here's an example using fsi:

We can pattern match on our new existing exception type just as easily as any other exception: