1#[derive(Clone, Debug, Eq, PartialEq)]
8pub enum ProgramError {
9 Custom(u32),
11 InvalidArgument,
12 InvalidInstructionData,
13 InvalidAccountData,
14 AccountDataTooSmall,
15 InsufficientFunds,
16 IncorrectProgramId,
17 MissingRequiredSignature,
18 AccountAlreadyInitialized,
19 UninitializedAccount,
20 NotEnoughAccountKeys,
21 AccountBorrowFailed,
22 MaxSeedLengthExceeded,
23 InvalidSeeds,
24 BorshIoError,
25 AccountNotRentExempt,
26 UnsupportedSysvar,
27 IllegalOwner,
28 MaxAccountsDataAllocationsExceeded,
29 InvalidRealloc,
30 MaxInstructionTraceLengthExceeded,
31 BuiltinProgramsMustConsumeComputeUnits,
32 InvalidAccountOwner,
33 ArithmeticOverflow,
34 Immutable,
35 IncorrectAuthority,
36}
37
38impl From<ProgramError> for u64 {
41 fn from(err: ProgramError) -> u64 {
42 match err {
43 ProgramError::Custom(0) => CUSTOM_ZERO,
44 ProgramError::Custom(code) => code as u64,
45 ProgramError::InvalidArgument => to_builtin(0),
46 ProgramError::InvalidInstructionData => to_builtin(1),
47 ProgramError::InvalidAccountData => to_builtin(2),
48 ProgramError::AccountDataTooSmall => to_builtin(3),
49 ProgramError::InsufficientFunds => to_builtin(4),
50 ProgramError::IncorrectProgramId => to_builtin(5),
51 ProgramError::MissingRequiredSignature => to_builtin(6),
52 ProgramError::AccountAlreadyInitialized => to_builtin(7),
53 ProgramError::UninitializedAccount => to_builtin(8),
54 ProgramError::NotEnoughAccountKeys => to_builtin(9),
55 ProgramError::AccountBorrowFailed => to_builtin(10),
56 ProgramError::MaxSeedLengthExceeded => to_builtin(11),
57 ProgramError::InvalidSeeds => to_builtin(12),
58 ProgramError::BorshIoError => to_builtin(13),
59 ProgramError::AccountNotRentExempt => to_builtin(14),
60 ProgramError::UnsupportedSysvar => to_builtin(15),
61 ProgramError::IllegalOwner => to_builtin(16),
62 ProgramError::MaxAccountsDataAllocationsExceeded => to_builtin(17),
63 ProgramError::InvalidRealloc => to_builtin(18),
64 ProgramError::MaxInstructionTraceLengthExceeded => to_builtin(19),
65 ProgramError::BuiltinProgramsMustConsumeComputeUnits => to_builtin(20),
66 ProgramError::InvalidAccountOwner => to_builtin(21),
67 ProgramError::ArithmeticOverflow => to_builtin(22),
68 ProgramError::Immutable => to_builtin(23),
69 ProgramError::IncorrectAuthority => to_builtin(24),
70 }
71 }
72}
73
74impl From<u64> for ProgramError {
75 fn from(code: u64) -> Self {
76 match code {
77 CUSTOM_ZERO => ProgramError::Custom(0),
78 c if c == to_builtin(0) => ProgramError::InvalidArgument,
79 c if c == to_builtin(1) => ProgramError::InvalidInstructionData,
80 c if c == to_builtin(2) => ProgramError::InvalidAccountData,
81 c if c == to_builtin(3) => ProgramError::AccountDataTooSmall,
82 c if c == to_builtin(4) => ProgramError::InsufficientFunds,
83 c if c == to_builtin(5) => ProgramError::IncorrectProgramId,
84 c if c == to_builtin(6) => ProgramError::MissingRequiredSignature,
85 c if c == to_builtin(7) => ProgramError::AccountAlreadyInitialized,
86 c if c == to_builtin(8) => ProgramError::UninitializedAccount,
87 c if c == to_builtin(9) => ProgramError::NotEnoughAccountKeys,
88 c if c == to_builtin(10) => ProgramError::AccountBorrowFailed,
89 c if c == to_builtin(11) => ProgramError::MaxSeedLengthExceeded,
90 c if c == to_builtin(12) => ProgramError::InvalidSeeds,
91 c if c == to_builtin(13) => ProgramError::BorshIoError,
92 c if c == to_builtin(14) => ProgramError::AccountNotRentExempt,
93 c if c == to_builtin(15) => ProgramError::UnsupportedSysvar,
94 c if c == to_builtin(16) => ProgramError::IllegalOwner,
95 c if c == to_builtin(17) => ProgramError::MaxAccountsDataAllocationsExceeded,
96 c if c == to_builtin(18) => ProgramError::InvalidRealloc,
97 c if c == to_builtin(19) => ProgramError::MaxInstructionTraceLengthExceeded,
98 c if c == to_builtin(20) => ProgramError::BuiltinProgramsMustConsumeComputeUnits,
99 c if c == to_builtin(21) => ProgramError::InvalidAccountOwner,
100 c if c == to_builtin(22) => ProgramError::ArithmeticOverflow,
101 c if c == to_builtin(23) => ProgramError::Immutable,
102 c if c == to_builtin(24) => ProgramError::IncorrectAuthority,
103 other => ProgramError::Custom(other as u32),
104 }
105 }
106}
107
108const BUILTIN_BIT_SHIFT: usize = 32;
114const CUSTOM_ZERO: u64 = 1_u64 << BUILTIN_BIT_SHIFT;
115
116#[inline(always)]
117const fn to_builtin(index: u64) -> u64 {
118 (index + 2) << BUILTIN_BIT_SHIFT
119}
120
121impl core::fmt::Display for ProgramError {
122 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
123 match self {
124 ProgramError::Custom(code) => write!(f, "Custom({code})"),
125 ProgramError::InvalidArgument => write!(f, "InvalidArgument"),
126 ProgramError::InvalidInstructionData => write!(f, "InvalidInstructionData"),
127 ProgramError::InvalidAccountData => write!(f, "InvalidAccountData"),
128 ProgramError::AccountDataTooSmall => write!(f, "AccountDataTooSmall"),
129 ProgramError::InsufficientFunds => write!(f, "InsufficientFunds"),
130 ProgramError::IncorrectProgramId => write!(f, "IncorrectProgramId"),
131 ProgramError::MissingRequiredSignature => write!(f, "MissingRequiredSignature"),
132 ProgramError::AccountAlreadyInitialized => write!(f, "AccountAlreadyInitialized"),
133 ProgramError::UninitializedAccount => write!(f, "UninitializedAccount"),
134 ProgramError::NotEnoughAccountKeys => write!(f, "NotEnoughAccountKeys"),
135 ProgramError::AccountBorrowFailed => write!(f, "AccountBorrowFailed"),
136 ProgramError::MaxSeedLengthExceeded => write!(f, "MaxSeedLengthExceeded"),
137 ProgramError::InvalidSeeds => write!(f, "InvalidSeeds"),
138 ProgramError::BorshIoError => write!(f, "BorshIoError"),
139 ProgramError::AccountNotRentExempt => write!(f, "AccountNotRentExempt"),
140 ProgramError::UnsupportedSysvar => write!(f, "UnsupportedSysvar"),
141 ProgramError::IllegalOwner => write!(f, "IllegalOwner"),
142 ProgramError::MaxAccountsDataAllocationsExceeded => {
143 write!(f, "MaxAccountsDataAllocationsExceeded")
144 }
145 ProgramError::InvalidRealloc => write!(f, "InvalidRealloc"),
146 ProgramError::MaxInstructionTraceLengthExceeded => {
147 write!(f, "MaxInstructionTraceLengthExceeded")
148 }
149 ProgramError::BuiltinProgramsMustConsumeComputeUnits => {
150 write!(f, "BuiltinProgramsMustConsumeComputeUnits")
151 }
152 ProgramError::InvalidAccountOwner => write!(f, "InvalidAccountOwner"),
153 ProgramError::ArithmeticOverflow => write!(f, "ArithmeticOverflow"),
154 ProgramError::Immutable => write!(f, "Immutable"),
155 ProgramError::IncorrectAuthority => write!(f, "IncorrectAuthority"),
156 }
157 }
158}