Exceptions
In Fβ―, thanks to Unions π, we can deal with expected errors using the Result type and optional union types for custom error - see π Railway oriented programming.
Still, as exceptions are quite common in .NET, Fβ― supports them fully and elegantly.
Type alias
Fβ― provides the convenientexn alias for the System.Exception type.
Defining exceptions
To define our own exceptions, we can use the exception keyword:
// Without inner data
exception ArgumentNullOrWhiteSpaceException
// With inner data
exception MustBePositiveException of int
// With inner data with labels
exception ArgumentMustBePositiveException of name: string * value: intβοΈ Notes:
Naming convention: the exception name should end with
ExceptionData labels are recommended for code clarity.
The syntax is close to a union type case for the exception's definition and its handling with pattern matching - see Full example below.
We can also define exceptions by inheriting from
System.Exception. This is the Cβ― style, but it is not recommended because it's less elegant for both definition and handling.
Throwing exceptions
Fβ― provides a set of convenient helpers:
raise (exn: exn)throw a custom exception object
equivalent of
throw exn;in Cβ―
reraise ()used in a
(try...) withblock to propagate a handled exception up the call chainequivalent of
throw;in Cβ―preserve the stack trace, contrary to
raise exto do the same outside of a
(try...) withblock, it's more complicated β π https://stackoverflow.com/a/41202215/8634147
failwith (message: string)andfailwithf (messageTemplate: string) (...args)generate a general Fβ― exception with the given message
failwithis the shortcut forraise (Exception message)failwithfis less used since Fβ― supports string interpolation.
invalidArg (argumentName: string) (message: string)generate a
System.ArgumentExceptionfor the given argument name and with the specified messageshortcut for
raise (ArgumentException(message, argumentName))
nullArg (argumentName: string)generate a
System.NullArgumentExceptionfor the given argument nameshortcut for
raise (ArgumentNullException argumentName)
invalidOp (message: string)generate a
System.InvalidOperationExceptionwith the given messageshortcut for
raise (InvalidOperationException message)
Examples:
Handling exceptions
β try/with expression
βοΈ Notes:
The keyword used is
with, notcatch, contrary to Cβ―.There is no
try/with/finallyexpression, onlytry/finallythat we can nest in anothertry/with.The
withblock is using pattern matching::? ExceptionTypeto check if the handled exception has or derives from the given type.Failure messageis an active pattern to catch low-level exceptions that have exactly theSystem.Exceptiontype. β useful to handle exceptions raised byfailwith(f)helpers.Exceptions defined using the
exceptionkeyword can be deconstructed β see Full example below.
Full example
The following example demonstrates almost every topic we studied:
How to define an exception type
How to raise an exception using different helpers
How to catch the exception and pattern match it
Pattern order
Pay attention to pattern order
:? ArgumentNullExceptionis placed before:? ArgumentExceptionbecause of the type inheritance relationship. Still, we are covered by the compiler: in case the 2 patterns are placed in the wrong order, we get the following warning:This rule will never be matchedFailureandArgumentMustBePositiveOrZeroExceptionpatterns can be placed anywhere above the last patternexnbecause they target specific types.The pattern
exnmust be placed at the end because it's the most general one.
Last updated
Was this helpful?