Creating Custom Errors
Learn how to create custom errors for your program
In the counter program, you used errors provided by solana_program
's ProgramError
enum that provides comprehensive but somewhat generic errors. These errors may work for some programs; however, some programs, for example, this voting program, may require more specific errors.
For example, you cannot use ProgramError::InvalidInstructionData
to handle scenarios where the voting window is closed or when the client passes less than 2 poll options, you need more descriptive errors.
To create custom errors, define a program-specific error enum and convert it to ProgramError
so you can return precise failures from your instructions.
Like so:
use num_enum::TryFromPrimitive;
use solana_program::program_error::ProgramError;
use solana_program_error::ToStr;
use thiserror::Error;
#[repr(u32)]
#[derive(Debug, Error, Clone, Copy, Eq, PartialEq, TryFromPrimitive)]
pub enum PollError {
#[error("You need at least 2 poll options")]
NotEnoughPollOptions = 6000,
#[error("End Slot cannot be less than start slot")]
InvalidSlotTime = 6001,
#[error("Voting window for this poll has closed")]
VotingWindowClosed = 6002,
#[error("Voting window for this poll is still open")]
VotingWindowStillOpen = 6003,
#[error("This poll has been closed")]
PollAlreadyClosed = 6004,
#[error("Input data exceeds max length")]
InvalidDataLength = 6005,
}
impl From<PollError> for ProgramError {
fn from(e: PollError) -> Self {
ProgramError::Custom(e as u32)
}
}
// Provide a static string for each variant (used by ProgramError::to_str::<PollError>())
impl ToStr for PollError {
fn to_str(&self) -> &'static str {
match self {
Self::NotEnoughPollOptions => "You need at least 2 poll options",
Self::InvalidSlotTime => "End Slot cannot be less than start slot",
Self::VotingWindowClosed => "Voting window for this poll has closed",
Self::VotingWindowStillOpen => "Voting window for this poll is still open",
Self::PollAlreadyClosed => "This poll has been closed",
Self::InvalidDataLength => "Input data exceeds max length",
}
}
}
Identify your error codes with large numbers to avoid clashes with other packages. For example, Solana's error code for insufficient balance is Custom(1)
.
thiserror::Error
gives each variant a readable message for logs and tests. Now you can use this enum as you’d ProgramError
.
Last updated on