Ecosystem.decode_error()
Elevator pitch:
When using solidity error definitions, the revert message (the inputs to the custom error) are not decoded (they are just bytes).
e.g.
ape.exceptions.ContractLogicError: b'\x9b\x0f\x01\xda\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;\x9a\xca\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
Let's do what we do best and dynamically generate a custom Exception class with the inputs as the properties!
Value:
Solidity projects that use custom errors.
Dependencies:
https://github.com/ApeWorX/ethpm-types/pull/29#pullrequestreview-961074682
Design approach:
Like structs, events, etc, let's create custom ContractLogicError classes that have the inputs as the properties on the class
So in your solidity, if you do:
error InsufficientFund(uint256 given, uint256 required);
function fund() public payable isOn {
if (msg.value > 0) {
revert InsufficientFund(msg.value, 1);
}
}
, you can access the custom error classes on the ContractInstance and they will be the exceptions raised for reverts in that case.
So you can do this in your tests:
with ape.reverts(contract.InsufficientFund) as err:
...
assert err.value.foo == 5
assert err.value.bar == 6
- Exactly like
pytest.raises()works.
NOTE: The original still has to work to as not be breaking:
with ape.reverts(message="revert reason"):
Task list:
- [ ] Tasks go here
Estimated completion date:
Design review:
Do not signoff unless:
-
- agreed the tasks and design approach will achieve acceptance, and
-
- the work can be completed by one person within the SLA. Design reviewers should consider simpler approaches to achieve goals.
(Please leave a comment to sign off)
Everything looks good, approved
Perhaps can use single dispatch to allow both message and exception class to be used in ape.reverts