Day 28: Error Enums
HardErrorEnumsFrom

Day 28: Error Enums

Solana programs use error enums with numeric codes for efficient error handling.

Solana Error Pattern

#[derive(Debug, Clone, Copy)]
#[repr(u32)]  // Each variant has a u32 code
pub enum ProgramError {
    NotInitialized = 0,
    AlreadyInitialized = 1,
    InvalidAuthority = 2,
    InsufficientFunds = 3,
}

In Solana, error codes are returned as u32 values in transaction logs. Having explicit codes makes debugging easier!

Why Numeric Codes?

  1. Efficient transmission: Only a u32 crosses the runtime boundary
  2. Clear logging: Error codes appear in transaction logs
  3. Client parsing: SDKs can decode error codes
  4. Versioning: New errors get new codes

Implementing Error Methods

impl ProgramError {
    fn code(&self) -> u32 {
        *self as u32
    }
    
    fn from_code(code: u32) -> Option<Self> {
        match code {
            0 => Some(Self::NotInitialized),
            1 => Some(Self::AlreadyInitialized),
            2 => Some(Self::InvalidAuthority),
            3 => Some(Self::InsufficientFunds),
            _ => None,
        }
    }
}

Anchor's Error Pattern

#[error_code]
pub enum MyError {
    #[msg("Account not initialized")]
    NotInitialized,  // Code: 6000
    
    #[msg("Invalid authority")]
    InvalidAuthority,  // Code: 6001
}

Error Conversion with From

impl From<ProgramError> for u32 {
    fn from(e: ProgramError) -> u32 {
        e as u32
    }
}

The Task

Implement for ProgramError:

  1. code() - returns the numeric error code
  2. from_code(code) - converts code back to error (if valid)

Requirements

  • ProgramError::InsufficientFunds.code()3
  • ProgramError::from_code(3)Some(InsufficientFunds)
  • ProgramError::from_code(99)None

Hints

fn code(&self) -> u32 {
    *self as u32
}

fn from_code(code: u32) -> Option<Self> {
    match code {
        0 => Some(Self::NotInitialized),
        1 => Some(Self::AlreadyInitialized),
        2 => Some(Self::InvalidAuthority),
        3 => Some(Self::InsufficientFunds),
        _ => None,
    }
}
Language: Rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Output
Run to see the result here.
    Day 28: Error Enums · RUST Challenge | learn.sol