1use {
2 num_traits::{FromPrimitive, ToPrimitive},
3 pinocchio::{msg, program_error::ProgramError},
4 thiserror::Error,
5};
6
7#[derive(Debug, Error)]
9pub enum Error {
10 #[error("Program is not executable")]
11 InvalidProgramExecutable,
12
13 #[error("Account is initialized yet")]
14 AccountNotInitialized,
15
16 #[error("The given account is not mutable")]
17 AccountNotMutable,
18
19 #[error("Account is not a signer")]
20 AccountNotSigner,
21
22 #[error("The current owner of this account is not the expected one")]
23 AccountOwnedByWrongProgram,
24
25 #[error("Failed to serialize or deserialize account data")]
26 BorshIoError,
27
28 #[error("Discriminator did not match what was expected")]
29 AccountDiscriminatorMismatch,
30
31 #[error("has_one constraint violated")]
32 HasOneConstraint,
33
34 #[error("Cannot initialize a program account with the payer account")]
35 TryingToInitPayerAsProgramAccount,
36}
37
38impl FromPrimitive for Error {
39 fn from_i64(n: i64) -> Option<Self> {
40 match n {
41 3000 => Some(Error::InvalidProgramExecutable),
42 3001 => Some(Error::AccountNotInitialized),
43 3002 => Some(Error::AccountNotMutable),
44 3003 => Some(Error::AccountNotSigner),
45 3004 => Some(Error::AccountOwnedByWrongProgram),
46 3005 => Some(Error::BorshIoError),
47 3006 => Some(Error::AccountDiscriminatorMismatch),
48 3007 => Some(Error::HasOneConstraint),
49 3008 => Some(Error::TryingToInitPayerAsProgramAccount),
50 _ => None,
51 }
52 }
53
54 fn from_u64(n: u64) -> Option<Self> {
55 Self::from_i64(n as i64)
56 }
57}
58
59impl ToPrimitive for Error {
60 fn to_i64(&self) -> Option<i64> {
61 match self {
62 Error::InvalidProgramExecutable => Some(3000),
63 Error::AccountNotInitialized => Some(3001),
64 Error::AccountNotMutable => Some(3002),
65 Error::AccountNotSigner => Some(3003),
66 Error::AccountOwnedByWrongProgram => Some(3004),
67 Error::BorshIoError => Some(3005),
68 Error::AccountDiscriminatorMismatch => Some(3006),
69 Error::HasOneConstraint => Some(3007),
70 Error::TryingToInitPayerAsProgramAccount => Some(3008),
71 }
72 }
73
74 fn to_u64(&self) -> Option<u64> {
75 self.to_i64().map(|n| n as u64)
76 }
77}
78
79impl From<Error> for ProgramError {
80 fn from(value: Error) -> Self {
81 msg!(&format!("[ERROR] {}", value));
82 ProgramError::Custom(value.to_u32().unwrap())
83 }
84}