Choice exercise error not caught by try-catch in Daml Script
I want to write a test in Daml Script which returns the error message returned by a failed choice exercise, but the error is not caught by the try-catch expression.
I would expect the test script below to succeed and return the error message as text, but it fails:
Script execution failed on commit at Main:49:5:
Unhandled exception: DA.Exception.AssertionFailed:AssertionFailed@3f4deaf145a15cdcfa762c058005e2edb9baa75bb7f95a4f8f6f937378e86415 with
message = "Cannot give Asset to yourself"
What am I doing wrong?
module Main where
import Daml.Script
type AssetId = ContractId Asset
template Asset
with
issuer : Party
owner : Party
name : Text
where
ensure name /= ""
signatory issuer
observer owner
key owner : Party
maintainer key
choice Give : AssetId
with
newOwner : Party
controller owner
do
assertMsg "Cannot give Asset to yourself" $ newOwner /= owner
create this with
owner = newOwner
setup : Script (Party, ContractId Asset)
setup = script do
-- user_setup_begin
alice <- allocatePartyWithHint "Alice" (PartyIdHint "Alice")
bob <- allocatePartyWithHint "Bob" (PartyIdHint "Bob")
aliceId <- validateUserId "alice"
bobId <- validateUserId "bob"
createUser (User aliceId (Some alice)) [CanActAs alice]
createUser (User bobId (Some bob)) [CanActAs bob]
-- user_setup_end
aliceTV <- submit alice do
createCmd Asset with
issuer = alice
owner = alice
name = "TV"
return (alice, aliceTV)
testAssertion : (Party, ContractId Asset) -> Script Text
testAssertion (alice, cid) = do
try do
submit alice $ exerciseCmd cid (Give alice)
pure "Shouldn't happen"
catch
(ex : AnyException) -> pure $ DA.Internal.Desugar.message ex
test : Script Text
test = setup >>= testAssertion
try/catch, which also has on-ledger-related semantics (persisting the rollback nodes of the transaction), is a bit of an odd feature in Daml Script, which is an off-ledger Daml runtime. Right now, this behavior is more or less expected and I don’t think there’s a plan to change this. If you want to test that something “successfully fails” you should use assertFail, as described in our documentation here as well.
Thanks, I agree, try/catch doesn’t make much sense in this way in Daml Script.
The limitation of submitMustFail (or assertFail for that matter) is that it cannot extract the error message from the update, but it seems I have to make do with what we have.