Exceptions
Last updated
Was this helpful?
Last updated
Was this helpful?
In FāÆ, thanks to Unions š, we can deal with expected errors using the Result type and optional union types for custom error - see š .
Still, as exceptions are quite common in .NET, F⯠supports them fully and elegantly.
F⯠provides the convenientexn
alias for the System.Exception
type.
To define our own exceptions, we can use the exception
keyword:
āļø Notes:
Naming convention: the exception name should end with Exception
Data 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.
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...) with
block to propagate a handled exception up the call chain
equivalent of throw;
in CāÆ
preserve the stack trace, contrary to raise ex
failwith (message: string)
and failwithf (messageTemplate: string) (...args)
generate a general F⯠exception with the given message
failwith
is the shortcut for raise (Exception message)
failwithf
is less used since F⯠supports string interpolation.
invalidArg (argumentName: string) (message: string)
generate a System.ArgumentException
for the given argument name and with the specified message
shortcut for raise (ArgumentException(message, argumentName))
nullArg (argumentName: string)
generate a System.NullArgumentException
for the given argument name
shortcut for raise (ArgumentNullException argumentName)
invalidOp (message: string)
generate a System.InvalidOperationException
with the given message
shortcut for raise (InvalidOperationException message)
Examples:
ā try/with
expression
āļø Notes:
The keyword used is with
, not catch
, contrary to CāÆ.
There is no try/with/finally
expression, only try/finally
that we can nest in another try/with
.
The with
block is using pattern matching:
:? ExceptionType
to check if the handled exception has or derives from the given type.
Failure message
is an active pattern to catch low-level exceptions that have exactly theSystem.Exception
type.
ā useful to handle exceptions raised by failwith(f)
helpers.
Exceptions defined using the exception
keyword can be deconstructed
ā see Full example below.
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
Pay attention to pattern order
:? ArgumentNullException
is placed before :? ArgumentException
because 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 matched
Failure
and ArgumentMustBePositiveOrZeroException
patterns can be placed anywhere above the last pattern exn
because they target specific types.
The pattern exn
must be placed at the end because it's the most general one.
to do the same outside of a (try...) with
block, it's more complicated
ā š