The Failure Type

One of the types you'll want to familiarize yourself with is Unison's Failure type. You'll see this type in the signatures of some of the functions in the base library, for example catch : '{g, Exception} a ->{g} Either Failure a. Failure is a unique type whose purpose is to capture information about an error.

Let's look at what we need to construct a failure.

As an example, constructing a Failure upon attempting to save a duplicate User database error might look like

failure.example1 : Failure
failure.example1 =
  Failure
    (typeLink DatabaseError)
    "The username column already contains a value for entry: Bob"
    (Any (User "Bob"))

The first argument to the data constructor for Failure is a Type.

You'll need to create a Type with the typeLink literal. The typelink literal allows us to represent a Unison type as a first class value.

Commonly, the type that we're linking to is some data type which represents the domain of the error, for example DatabaseError or Generic.

The second argument to Failure is a Text body which should be a descriptive error message.

The third argument is of type Any. Any is another Unison built-in. It wraps any unison value. For example:

Any 42
Any 42

or

You can use Any to capture the value that has produced the error result. If that value is not useful for error reporting, you can always use Unit as a placeholder, Any ().

📚 Unison provides a helpful Generic failure constructor, Generic.failure for when you don't have a particular type that models your error domain. It takes in an error message and a value of any type to produce a Failure: Generic.failure : Text -> a -> Failure

genericFailure : Failure
genericFailure =
  Generic.failure
    "A failure occurred when accessing the user" (User "Ada")