Solana programs use error enums with numeric codes for efficient error handling.
#[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!
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,
}
}
}#[error_code]
pub enum MyError {
#[msg("Account not initialized")]
NotInitialized, // Code: 6000
#[msg("Invalid authority")]
InvalidAuthority, // Code: 6001
}impl From<ProgramError> for u32 {
fn from(e: ProgramError) -> u32 {
e as u32
}
}Implement for ProgramError:
code() - returns the numeric error codefrom_code(code) - converts code back to error (if valid)ProgramError::InsufficientFunds.code() → 3ProgramError::from_code(3) → Some(InsufficientFunds)ProgramError::from_code(99) → Nonefn 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,
}
}