use core::fmt;
use solana_instruction_error::InstructionError;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ProgramError {
InvalidArgument,
InvalidInstructionData,
InvalidAccountData,
AccountDataTooSmall,
InsufficientFunds,
IncorrectProgramId,
MissingRequiredSignature,
AccountAlreadyInitialized,
UninitializedAccount,
MissingAccount,
InvalidSeeds,
ArithmeticOverflow,
AccountNotRentExempt,
InvalidAccountOwner,
IncorrectAuthority,
Immutable,
BorshIoError,
ComputeBudgetExceeded,
Custom(u32),
Runtime(String),
}
impl From<InstructionError> for ProgramError {
fn from(err: InstructionError) -> Self {
#[allow(deprecated)]
match err {
InstructionError::InvalidArgument => Self::InvalidArgument,
InstructionError::InvalidInstructionData => Self::InvalidInstructionData,
InstructionError::InvalidAccountData => Self::InvalidAccountData,
InstructionError::AccountDataTooSmall => Self::AccountDataTooSmall,
InstructionError::InsufficientFunds => Self::InsufficientFunds,
InstructionError::IncorrectProgramId => Self::IncorrectProgramId,
InstructionError::MissingRequiredSignature => Self::MissingRequiredSignature,
InstructionError::AccountAlreadyInitialized => Self::AccountAlreadyInitialized,
InstructionError::UninitializedAccount => Self::UninitializedAccount,
InstructionError::MissingAccount | InstructionError::NotEnoughAccountKeys => {
Self::MissingAccount
}
InstructionError::InvalidSeeds => Self::InvalidSeeds,
InstructionError::ArithmeticOverflow => Self::ArithmeticOverflow,
InstructionError::AccountNotRentExempt => Self::AccountNotRentExempt,
InstructionError::InvalidAccountOwner => Self::InvalidAccountOwner,
InstructionError::IncorrectAuthority => Self::IncorrectAuthority,
InstructionError::Immutable => Self::Immutable,
InstructionError::BorshIoError => Self::BorshIoError,
InstructionError::ComputationalBudgetExceeded => Self::ComputeBudgetExceeded,
InstructionError::Custom(code) => Self::Custom(code),
other => Self::Runtime(format!("{other:?}")),
}
}
}
impl fmt::Display for ProgramError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidArgument => write!(f, "invalid argument"),
Self::InvalidInstructionData => write!(f, "invalid instruction data"),
Self::InvalidAccountData => write!(f, "invalid account data"),
Self::AccountDataTooSmall => write!(f, "account data too small"),
Self::InsufficientFunds => write!(f, "insufficient funds"),
Self::IncorrectProgramId => write!(f, "incorrect program id"),
Self::MissingRequiredSignature => write!(f, "missing required signature"),
Self::AccountAlreadyInitialized => write!(f, "account already initialized"),
Self::UninitializedAccount => write!(f, "uninitialized account"),
Self::MissingAccount => write!(f, "missing account"),
Self::InvalidSeeds => write!(f, "invalid seeds"),
Self::ArithmeticOverflow => write!(f, "arithmetic overflow"),
Self::AccountNotRentExempt => write!(f, "account not rent-exempt"),
Self::InvalidAccountOwner => write!(f, "invalid account owner"),
Self::IncorrectAuthority => write!(f, "incorrect authority"),
Self::Immutable => write!(f, "account is immutable"),
Self::BorshIoError => write!(f, "borsh serialization error"),
Self::ComputeBudgetExceeded => write!(f, "compute budget exceeded"),
Self::Custom(code) => write!(f, "custom program error: {code} ({code:#x})"),
Self::Runtime(msg) => write!(f, "runtime error: {msg}"),
}
}
}