If we have a complex clause in ensure or assert checks, anyway to notifiy thecaller what condition or subcondition really failed?
For ensure conditions you cannot get more information atm. For asserts you have two options:
- Instead of having a single call to
assert, make multiple calls toassertMsgwith different strings. The string will appear in the error so you can use that to figure out which one failed. - Using
assertMsgworks well if you want the error for debugging. If you actually need to consume it from code, parsing the string in the error is a rather fragile approach and you probably want a structured error instead of a simple string. In that caseassertorassertMsgisn’t going to help. However, you have another option: The choice result. Let’s make a simple example:
choice C : ()
controller p
do assert conditionA
assert conditionB
pure ()
The only thing that choice will do if it succeeds is to archive the contract (it is a consuming choice).
Now we can modify that as follows:
nonconsuming choice C : Either Error ()
controller p
do if conditionA
then if conditionB
then do archive self
pure (Right ())
else pure (Left ErrorB)
else pure (Left ErrorA)
data Error = ErrorA | ErrorB
You’ll notice a few things:
- I’ve made the choice nonconsuming. This is because if the assertions fail we still need to return a value from the choice but do not want to archive the contract.
- I’ve changed the return type to
Either Error ()and introduced a newErrortype. - I’ve replaced the assertions by
ifstatements. There are various ways to make this nicer than the nested ifs here but I’ve deliberately kept things as simple as possible.
There is one important difference here: The nonconsuming choice will always be recorded on the ledger even if the assertions fail. This is not necessarily an issue and in some applications this is even desirable but it is something you have to keep in mind.
Overall, if you do not need to consume the error programmatically and you do not need to record the error on the ledger, assertMsg is much simpler and preferable.