How do I catch an inbuilt Exception in a Script?

I’m trying to handle an inbuilt exception in a Script. Using the getting-started User example, I’ve written this test, trying to handle an assertion failure and just log the error message:

my_test : Script ()
my_test = script do
  alice <- allocateParty "Alice"
  bob <- allocateParty "Bob"

  aliceUserCid <- submit alice do
    createCmd User with username = alice; following = []
  bobUserCid <- submit bob do
    createCmd User with username = bob; following = []

  aliceUserCid <- submit alice do
    exerciseCmd aliceUserCid Follow with userToFollow = bob

  try do
    aliceUserCid <- submit alice do
      exerciseCmd aliceUserCid Follow with userToFollow = bob
    return ()
  catch
    AssertionFailed m -> debug m
    GeneralError m -> debug m
  return ()

However, I get the error

  Unhandled exception:  DA.Exception.AssertionFailed:AssertionFailed@3f4deaf145a15cdcfa762c058005e2edb9baa75bb7f95a4f8f6f937378e86415 with
                          message = "You cannot follow the same user twice"

This is surprising since AssertionFailed is one of the cases in my catch block. What am I doing wrong?
This is using SDK 1.16.0.

3 Likes

Exceptions are not propagated across submit.

We could fix that reasonably easily in Daml Studio but they are not exposed over the Ledger API (beyond in the string error message) atm and one of the guiding principles of Daml Script is to keep the behavior in Daml Studio aligned with what you can do over the Ledger API.

2 Likes