Skip to content

G. Error Handling

Back to Solidity Feature Support

FeatureStatusNotes
require(condition)Maps to NeoVM ASSERT.
require(condition, "msg")ASSERT with message.
require(condition, CustomError(...))Error name and arg count preserved in NeoVM THROW message.
assert(condition)Maps to NeoVM ASSERT.
revert()Maps to NeoVM ABORT.
revert("message")ABORT with message.
revert CustomError(...)Named revert with arguments.
Custom error definitionserror X(...) parsed and used in revert statements.
try / catchNeoVM TRY/ENDTRY structured exception handling.
try with return bindingtry f() returns (uint r) { ... } supported.
Multiple catch clausesLowered with EVM-canonical 4-byte selector guards (Task #103). catch Panic(uint256) matches 0x4e487b71, catch Error(string) matches 0x08c379a0, catch (bytes) binds the raw envelope. User-defined named error clauses retain the legacy permissive ISTYPE guard.

Partial error handling details

Multiple catch clauses — Task #103 switched the dispatcher to EVM-canonical selector matching. catch Panic(uint256) and catch Error(string) now guard on the 4-byte keccak selector (0x4e487b71, 0x08c379a0) at the head of the revert envelope, decoding code / msg via StdLib.abiDecode and SUBSTR. User-defined named catches (e.g. catch CustomErr(uint c)) retain the pre-#103 ISTYPE guard until a follow-up extends selector-based routing to custom errors.

solidity
// ✅ Recommended — single catch clause
try target.someFunction() returns (uint256 result) {
    // success
} catch (bytes memory reason) {
    // handle any failure
}

// ⚠️ Works but with caveats — multiple catch clauses
try target.someFunction() returns (uint256 result) {
    // success
} catch Error(string memory reason) {
    // string exceptions routed here
} catch (bytes memory lowLevelData) {
    // everything else
}

MIT Licensed