# Difference between \`error\` and \`fail\`

**URL:** <https://forum.canton.network/t/difference-between-error-and-fail/1286>\
**Category:** App Development\
**Created:** [September 24, 2020, 10:15am UTC](https://forum.canton.network/t/difference-between-error-and-fail/1286 "2020-09-24T10:15:46Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![georg](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/georg/32/368_2.png) [@georg](https://forum.canton.network/u/georg)\
**Post date:** [September 24, 2020, 10:15am UTC](https://forum.canton.network/t/difference-between-error-and-fail/1286/1 "2020-09-24T10:15:46Z")

</div>

**Mod note: As of SDK 1.5.0 Scenarios have been superseded by the more powerful [Daml Script](https://docs.daml.com/daml-script/index.html). We now recommend using that for all purposes. [For more information, and to learn how to use Script please check out @Andreas’ post on our blog](https://daml.com/blog/engineering/daml-script-scenarios-2-0/).**

I just tracked down a bug in my code that I found quite hard (and surprising) to discover. It was related to the difference between `error` and `fail`, so I wanted to ask for some clarification on this.

I have the following function:

```haskell
oneOrNone : Optional a -> Optional a -> Optional a
oneOrNone (Some x) (Some y) = fail "Only one of the optionals may be set"
oneOrNone (Some x) None = Some x
oneOrNone None (Some y) = Some y
oneOrNone None None = None

```

The following test case passes, which is (at first) unexpected:

```haskell
test = scenario do
  let
    x = Some "x"
    y = Some "y"
    z = oneOrNone x y
  assert $ z == None

```

It means my function above returns `None` in the case with the `fail`.

Intuitively, I expected `fail` to just abort the transaction with the corresponding error message. But apparently `fail` works according to the `ActionFail` type class implementation, which in the case of `Optional` seems to just return `None`, discarding the error message. The docs for `fail` don’t really explain this behaviour well, just stating: `Fail with an error message.`

I think my misconception came from the fact that `fail` indeed aborts the transaction when I’m in the `Update` or `Scenario` monad. I just hadn’t realized that that behaviour changes when I’m in the `Optional` context. It was in fact `error` that I should’ve used, which seems to do what I wanted here.

So I guess I’ve figured out _why_ I’ve produced this bug. But could anyone shed some light on the two functions, when to use each, and how exactly `error` works? The documentation of `error` is not quite clear: it states that “within a transaction” it will abort it. But in my example test case I’m not in any transaction context afaics. So how exactly does this work?

A related question: does the `ActionFail` instance on `Optional` (and also `[]`, which I assume produces an empty list) even make sense? What would be valid use cases for `fail` within the `Optional` or list monad, wouldn’t I just return None, resp. [] directly instead, as the error message for `fail` is discarded anyway?

Appreciate any insights on how to better make sense of these functions.

---

<div class="post-metadata">

**Author:** ![bernhard](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/bernhard/32/356_2.png) [@bernhard](https://forum.canton.network/u/bernhard)\
**Post date:** [September 24, 2020, 10:22am UTC](https://forum.canton.network/t/difference-between-error-and-fail/1286/2 "2020-09-24T10:22:02Z")

</div>

`fail` is an alias of `abort`. The difference between `error` and `abort` is covered in this section of the Introduction to DAML: [https://docs.daml.com/daml/intro/5\_Restrictions.html](https://docs.daml.com/daml/intro/5_Restrictions.html)  
I think it should answer most of your questions, except on the `ActionFail` instances. And while I agree that it might be a bit surprising at first, these are the standard implementations and taken over from Haskell. An example which may be a bit more intuitive is the instance for `Either Text`, where `abort t = Left t`.

---

<div class="post-metadata">

**Author:** ![cocreature](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/cocreature/32/36_2.png) [@cocreature](https://forum.canton.network/u/cocreature)\
**Post date:** [September 24, 2020, 10:49am UTC](https://forum.canton.network/t/difference-between-error-and-fail/1286/3 "2020-09-24T10:49:04Z")

</div>

`ActionFail` exists primarily of do-notation. In a `do`-block you can write something like:

```haskell
do Some x <- _

```

You have to handle the pattern match failure somehow. There are two options:

1. You always crash like for a pattern-match failure in a `case` statement.
2. You make the pattern match failure depend on the type of `Action` and therefore make it configurable.

Haskell chose option 2 (and DAML inherits this from Haskell) which led to the behavior for `Optional` and `[]` you know. This can often be convenient for filtering in things like lists, e.g., a very simple implementation of `mapOptional` can look as follows:

```haskell
mapOptional f xs = do
  Some x <- map f xs
  pure x

```

---

<div class="post-metadata">

**Author:** ![Stephen](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/stephen/32/102_2.png) [@Stephen](https://forum.canton.network/u/Stephen)\
**Post date:** [September 24, 2020, 4:14pm UTC](https://forum.canton.network/t/difference-between-error-and-fail/1286/4 "2020-09-24T16:14:35Z")

</div>

> [@georg](#):
>
> A related question: does the `ActionFail` instance on `Optional` (and also `[]` , which I assume produces an empty list) even make sense?

Consider this `do` block, where `foo`, `bar`, `baz`, and `quux` stand for arbitrary steps in the `do`:

```haskell
do
  foo
  bar
  fail "hi there"
  baz
  quux

```

Now consider this `do` evaluated in either `Optional` or `[]`, where `fail` will return `None` or `[]` respectively. **Because of this value, `baz` and `quux` will never be reached.** That is more or less all we ask of a correct `ActionFail` instance, and it naturally holds in this example for `Update` and `Scenario` as well.

> [@georg](#):
>
> What would be valid use cases for `fail` within the `Optional` or list monad, wouldn’t I just return None, resp. directly instead, as the error message for `fail` is discarded anyway?

Aside from most occurrences happening implicitly as a result of a pattern, as @cocreature describes, you might want to use it to be generic over these choices.

I would say, as a matter of practice, to use `fail` instead of `error` when possible, because `fail` is less “magical” than `error`, i.e. a function that can abort by `fail` must reflect that in its type, whereas `error` works anywhere, invisibly.
