Return custom errors#

This guide shows how to return custom errors from your Rust smart contract.

Defining and deriving#

Custom error codes help communicate why a contract rejects and can be returned both during initialization and during updates.

On-chain, smart contracts return a numeric error code when rejecting. This is also the case when using a custom error type. Therefore, a mapping from the custom error type to Reject, in the form of an implementation of From<MyError> for Reject, is needed. You can also derive it automatically using #[derive(Reject)]:

#[derive(Reject)]
enum MyError {
    ErrOne,
    ErrTwo,
}

Note

The valid range of error codes is i32::MIN..-1. When deriving Reject, each variant is assigned an error code as determined by the ordering. First variant (ErrOne in example) gets -1, second variant (ErrTwo in example) gets -2, and so on.

Warning

Deriving Reject is only possible for fieldless enums, i.e., enums where the variants do not have associated data. Additionally, derivation for enums with custom discriminant values is not supported either.

Using custom errors#

Return custom errors, as you would with any other error type:

#[init(contract = "my_contract")]
fn contract_init_my(
    _ctx: &impl HasInitContext<()>,
) -> Result<State, MyError> { Err(MyError::ErrOne) }

#[receive(contract = "my_contract", name = "my_receive")]
fn contract_receive_my<A: HasActions>(
    _ctx: &impl HasReceiveContext<()>,
    _state: &mut State,
) -> Result<A, MyError> { Err(MyError::ErrTwo) }

Standard error codes#

The following standard error codes exist:

Variant

Error code

()

i32::MIN + 1 (-2147483647)

ParseError

i32::MIN + 2 (-2147483646)

LogError::Full

i32::MIN + 3 (-2147483645)

LogError::Malformed

i32::MIN + 4 (-2147483644)

NewContractNameError::MissingInitPrefix

i32::MIN + 5 (-2147483643)

NewContractNameError::TooLong

i32::MIN + 6 (-2147483642)

NewContractNameError::ContainsDot

i32::MIN + 9 (-2147483639)

NewContractNameError::InvalidCharacters

i32::MIN + 10 (-2147483638)

NewReceiveNameError::MissingDotSeparator

i32::MIN + 7 (-2147483641)

NewReceiveNameError::TooLong

i32::MIN + 8 (-2147483640)

NewReceiveNameError::InvalidCharacters

i32::MIN + 11 (-2147483637)

NotPayableError

i32::MIN + 12 (-2147483636)

The error codes are also listed in the library documentation on docs.rs.

Was this article helpful?
Legal information