`submitMustFailWith`
I was going to suggest the addition of a submitMustFailWith or equivalent to the SDK.
The use-case I have for this, is for example that I want to check that a transaction fails due to a failed precondition (e.g. asset quantity must be positive), rather than say, a missing controller - the current submitMustFail doesn’t discriminate between the two. This can be done with a trycatch_ clause.
I’ve factored this out into:
submitMustFailWith : forall e m cmds a . (Exception e, ActionCatch m, HasSubmit m cmds, HasCallStack)
=> Party
-> cmds a
-> m ()
submitMustFailWith party cmds =
try do
void $ submit party cmds
throw $ AssertionFailed "Submit should have failed but passed"
catch
(_ : e) ->
pure ()
testSplit = script do
...
mint <- submitMulti [registrar, alice] [] $ createCmd Holding with
instrument = usd
quantity = 1000.0
submitMustFailWith @PreconditionFailed alice $ exerciseCmd mint Split with splitQuantity = 2000.0
But the result is still
daml/Daml/Finance.daml|91 col 1| Script:Error:Scenario execution failed on commit at Daml.Finance:85:12: Unhandled exception: DA.Exception.PreconditionFailed:PreconditionFailed@f20de1e4e37b92280264c08bf15eca0be0bc5babd7a7b5e574997f154c00cb78 with message = "Template precondition violated: Holding {regulators = Set [], registrars = Set ['registrar'], creditors = Set [], beneficiaries = Set ['alice'], subcustodians = ['registrar'], instrument = <contract-id>, quantity = -1000.0}" Ledger time: 1970-01-01T00:00:00Z Partial transaction: Failed exercise (unknown source): exercises Split on #1:0 (Daml.Finance:Holding) with splitQuantity = 2000.0000000000 Sub-transactions: 0 └─> 'alice' exercises Split on #1:0 (Daml.Finance:Holding) with splitQuantity = 2000.0000000000 children: 1 └─> create Daml.Finance:Holding with regulators = (DA.Set.Types:Set@97b883cd8a2b7f49f90d5d39c981cf6e110cf1f1c64427a28a6d58ec88c43657 with map = GenMap[]); registrars = (DA.Set.Types:Set@97b883cd8a2b7f49f90d5d39c981cf6e110cf1f1c6442
Am I writing the try/catch correctly?
Does this function seem like a sensible addition to the SDK?
It’s definitely a sensible idea. We had a PR from @matt Give the reason for failure on `mustFail` nodes in scenarios by mjstewart · Pull Request #6517 · digital-asset/daml · GitHub which tried to add something like that but never got over the finish line.
There is an issue here in that we generally try very hard that everything that you can do in Daml Studio is also available over the ledger API. However, the ledger API does not expose the Daml exception that got thrown in your transaction so while we could expose this in Daml Studio, we cannot expose it in Daml script.
And there are also a number of non-exception failures from authorization failures to mistyped contract ids, … which will need a slightly different API.
I think it’s probably worth exposing something for this even if it just works in Daml Studio but it still needs some thought and a fair amount of implementation.
So I’m a bit confused now.
I’ve just written a simple try/catch block, and it’s not working either:
try do
void $ submit alice $ exerciseCmd mint Split with splitQuantity = 2000.0
-- error "Expected: PreconditoionFailed"
catch
PreconditionFailed{} -> pure ()
When you said
while we could expose this in Daml Studio, we cannot expose it in Daml script.
Do you essentially mean that try/catch is broken in daml Script? (But that it works inside an Update?)
It’s not broken in Daml script. If you throw in Script you can catch it. What doesn’t work is throwing an exception in a submission` and expecting to catch that exception on the client side. See How do I catch an inbuilt Exception in a Script? - #2 by cocreature for the same discussion.
Duplicate of
Hey team, I’m writing some scripts to test some new features I’ve recently added to a Daml project. One thing I noticed is when I do negative testing, using submitMustFail that I’d like to also provide the reason why the submission should fail. Currently, I have to manually check that the submission failed as I cannot specify the reason why the submission should fail. For example, I have choices that requires multiple signatures with multiple assertions. I cannot distinguish a failure on a mis…