Feedback wanted: Catching Custom Errors / default catch clause

Solidity does not yet support catching custom errors. This is because the implementation is difficult for the following reason: If the error selector matches a catch clause but decoding of the error data fails (e.g. because of an out-of-bounds data pointer), execution continues in the catch (bytes memory _data) {...} clause. Because of that, we have to modify the ABI decoder to return a status code instead of reverting directly in this case.

The reasoning behind this behaviour was that the default catch clause can catch “everything” (note that there can also be collisions in the four bytes selector).

The implementation would be much easier if we could just say that decoding failures in the error data lead to the revert data being forwarded with a revert.

This would also be consistent with how return data is handled: There, we cannot jump into a catch clause because the call did not revert (and thus state changes still take effect). So with this change, decoding errors lead to a revert both in the success and the failure case.

This is of course a breaking change, so we can only do this starting from 0.9.0. Until then, we can still have almost the same behaviour without a breaking change if there is no default catch clause.

Any opinions on this change? Also it would be nice to know in which situations you want to catch custom errors.

2 Likes

I recently wanted to catch a custom error and work around using the default catch and realized that it was not trivial to get the error selector from the error bytes memory. If there is an easy way to split/ match the error selector and return the rest of the bytes to do whatever you want (e.g. ignore the data or use abi.decode) would already be a big improvement that would not be a breaking change, right?

The situation where I looked into this was around handling 0x rich errors, which are similar to the custom solidity errors. I would also see that for a lot of the exchanges and defi protocols this would allow to easily build on top of each other.

Linking a Twitter thread here since it seems relevant and has some feedback on the “in which situations you want to catch custom errors?” question.

Is there something that makes this difficult to do?

Not really difficult, but maybe rather error-prone: It means we have to add a flag to every function that generates an abi decoding function and change the way it is called depending on that flag. It also means the control-flow gets more complicated.