Skip to main content

ExitCode

Enum ExitCode 

Source
#[repr(i32)]
pub enum ExitCode {
Show 29 variants Ok = 0, Panic = -1, InterruptionCalled = -3, RootCallOnly = -1_002, MalformedBuiltinParams = -1_003, CallDepthOverflow = -1_004, NonNegativeExitCode = -1_005, UnknownError = -1_006, InputOutputOutOfBounds = -1_007, PrecompileError = -1_008, NotSupportedBytecode = -1_009, StateChangeDuringStaticCall = -1_010, CreateContractSizeLimit = -1_011, CreateContractCollision = -1_012, CreateContractStartingWithEF = -1_013, OutOfMemory = -1_014, UnreachableCodeReached = -2_001, MemoryOutOfBounds = -2_002, TableOutOfBounds = -2_003, IndirectCallToNull = -2_004, IntegerDivisionByZero = -2_005, IntegerOverflow = -2_006, BadConversionToInteger = -2_007, StackOverflow = -2_008, BadSignature = -2_009, OutOfFuel = -2_010, UnknownExternalFunction = -2_011, UnexpectedFatalExecutionFailure = -3_001, MissingStorageSlot = -3_002,
}
Expand description

Exit codes representing various execution outcomes and error conditions.

This enum defines the possible exit codes that can be returned by the execution environment.

The codes are grouped into several categories:

  • Basic status codes (0 to -2)
  • Fluentbase-specific error codes (-1000 and below)
  • Trap error codes (-2000 and below)

Note: Exit codes cannot be positive, as positive values are used to represent call indices in interrupted executions.

Exit codes are used to represent the outcome of execution across different environments. This makes their interpretation somewhat nuanced.

Within applications, developers can use any exit code, but there are conventions:

  1. Ok (0) — Indicates successful execution.
  2. Panic (-1) — Controlled application reverts (intended error, no gas penalty).
  3. Any other code is treated as an error with a gas penalty and is mapped to Err (-2).

Technically, developers can return trap codes, but it’s generally pointless: they are replaced by the Err (-2) code and still incur gas penalties. If the error code cannot be determined, it is mapped to UnknownError (-1006), which also results in a gas fine.

The SDK provides helper functions such as evm_exit and evm_panic to simplify returning error codes. These produce Solidity-compatible error outputs.

The exit function remains available to all developers. In some cases, an application may want to simulate trap behavior or explicitly exit with a gas penalty to comply with gas consumption standards (for instance, EVM runtime).

This behavior is similar to Solidity, where only three exit codes are supported:

  • For legacy contracts: Ok = 1, Revert = 0, Err = 2
  • For EOF contracts: Ok = 0, Revert = 1, Err = 2

§Basic Status Codes

  • Ok (0) - Successful execution
  • Panic (-1) - Execution panic
  • Err (-2) - General error

§Fluentbase Error Codes

  • RootCallOnly - Operation restricted to root-level calls
  • MalformedBuiltinParams - Invalid parameters passed to builtin function
  • CallDepthOverflow - Call stack depth exceeded limit
  • NonNegativeExitCode - Exit code must be negative
  • UnknownError - Unspecified error condition
  • InputOutputOutOfBounds - I/O operation exceeded bounds
  • PrecompileError - Error in precompiled contract execution

§Trap Error Codes

  • UnreachableCodeReached - Execution reached unreachable code
  • MemoryOutOfBounds - Memory access violation
  • TableOutOfBounds - Table access violation
  • IndirectCallToNull - Attempted call to null function pointer
  • IntegerDivisionByZero - Division by zero
  • IntegerOverflow - Integer overflow occurred
  • BadConversionToInteger - Invalid integer conversion
  • StackOverflow - Stack limit exceeded
  • BadSignature - Invalid function signature
  • OutOfFuel - Insufficient gas/fuel for execution
  • GrowthOperationLimited - Growth operation exceeded limits
  • UnresolvedFunction - Function not found

Variants§

§

Ok = 0

Execution is finished without errors

§

Panic = -1

Panic is produced by a program (aka revert)

§

InterruptionCalled = -3

An interruption created by runtime (only for system contracts)

§

RootCallOnly = -1_002

Function can only be invoked as the root entry call

§

MalformedBuiltinParams = -1_003

Builtin function received malformed or invalid parameters

§

CallDepthOverflow = -1_004

Exceeded maximum allowed call stack depth

§

NonNegativeExitCode = -1_005

Exit code must be non-negative, but a negative value was used

§

UnknownError = -1_006

Generic catch-all error for unknown failures

§

InputOutputOutOfBounds = -1_007

I/O operation tried to read/write outside allowed buffer bounds

§

PrecompileError = -1_008

An error happens inside a precompiled contract

§

NotSupportedBytecode = -1_009

Passed bytecode into executor is not supported

§

StateChangeDuringStaticCall = -1_010

State changed inside immutable call (static=true)

§

CreateContractSizeLimit = -1_011

Create a contract size limit reached (limit depends on the application type)

§

CreateContractCollision = -1_012

There is a collision on the contract creation (the same address is derived)

§

CreateContractStartingWithEF = -1_013

Created contract starts with invalid bytes (0xEF).

§

OutOfMemory = -1_014

A program runs out of memory (max memory pages reached)

§

UnreachableCodeReached = -2_001

Execution reached a code path marked as unreachable

§

MemoryOutOfBounds = -2_002

Memory access outside the allocated memory range

§

TableOutOfBounds = -2_003

Table index access outside the allocated table range

§

IndirectCallToNull = -2_004

Indirect function call attempted with a null function reference

§

IntegerDivisionByZero = -2_005

Division or remainder by zero occurred

§

IntegerOverflow = -2_006

Integer arithmetic operation overflowed the allowed range

§

BadConversionToInteger = -2_007

Invalid conversion to integer (e.g., from NaN or out-of-range value)

§

StackOverflow = -2_008

Stack reached its limit (overflow or underflow)

§

BadSignature = -2_009

Function signature mismatch in a call

§

OutOfFuel = -2_010

Execution ran out of allocated fuel/gas

§

UnknownExternalFunction = -2_011

Call an undefined or unregistered external function

§

UnexpectedFatalExecutionFailure = -3_001

An unexpected fatal execution failure (node should panic or terminate the execution)

§

MissingStorageSlot = -3_002

Missing storage slot

Implementations§

Source§

impl ExitCode

Source

pub const fn from_repr(discriminant: i32) -> Option<ExitCode>

Try to create Self from the raw representation

Source§

impl ExitCode

Source

pub fn is_trap_code(&self) -> bool

Check if the exit code represents a trap code

Source§

impl ExitCode

Source

pub fn is_ok(&self) -> bool

Source

pub fn is_revert(&self) -> bool

Returns whether the result is a revert.

Source

pub fn is_error(&self) -> bool

Source

pub fn is_fatal_exit_code(&self) -> bool

Check if the exit code represents a fatal error

Fatal exit code means that the application terminated unexpectedly, for example, by having out of fuel or memory out of bounds. It means that we can’t handle the output state of this contract gracefully.

Source

pub const fn into_i32(self) -> i32

Trait Implementations§

Source§

impl Clone for ExitCode

Source§

fn clone(&self) -> ExitCode

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ExitCode

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for ExitCode

Source§

fn default() -> ExitCode

Returns the “default value” for a type. Read more
Source§

impl Display for ExitCode

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Error for ExitCode

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0:

use the Display impl or to_string()

1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<&TrapCode> for ExitCode

Source§

fn from(value: &TrapCode) -> Self

Converts to this type from the input type.
Source§

impl From<ExitCode> for i32

Source§

fn from(value: ExitCode) -> Self

Converts to this type from the input type.
Source§

impl From<TrapCode> for ExitCode

Source§

fn from(value: TrapCode) -> Self

Converts to this type from the input type.
Source§

impl From<i32> for ExitCode

Source§

fn from(value: i32) -> Self

Converts to this type from the input type.
Source§

impl Hash for ExitCode

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for ExitCode

Source§

fn eq(&self, other: &ExitCode) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Copy for ExitCode

Source§

impl Eq for ExitCode

Source§

impl StructuralPartialEq for ExitCode

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSend for T
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_sync(self: Box<T>) -> Box<dyn Any + Send + Sync>

Converts Box<Trait> (where Trait: DowncastSync) to Box<dyn Any + Send + Sync>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Converts Arc<Trait> (where Trait: DowncastSync) to Arc<Any>, which can then be downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<T> FmtForward for T

Source§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
Source§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
Source§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
Source§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
Source§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
Source§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
Source§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
Source§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
Source§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Pipe for T
where T: ?Sized,

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
Source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
Source§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
Source§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
Source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> Tap for T

Source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
Source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
Source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
Source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
Source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
Source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
Source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
Source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
Source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
Source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.