typhoon_errors/
lib.rs

1mod default_custom;
2mod error_code;
3mod extension;
4
5use pinocchio::{
6    log::sol_log,
7    program_error::{ProgramError, ToStr},
8};
9pub use {default_custom::*, error_code::*, extension::*};
10
11pub enum ErrorType<T>
12where
13    T: 'static + ToStr + TryFrom<u32>,
14{
15    Solana(ProgramError),
16    Typhoon(ErrorCode),
17    Custom(T),
18}
19
20pub struct Error<T = CustomError>
21where
22    T: 'static + ToStr + TryFrom<u32>,
23{
24    error: ErrorType<T>,
25    account_name: Option<String>,
26}
27
28impl<T> Error<T>
29where
30    T: 'static + ToStr + TryFrom<u32>,
31{
32    pub fn new_solana(error: ProgramError) -> Self {
33        Self {
34            error: ErrorType::Solana(error),
35            account_name: None,
36        }
37    }
38
39    pub fn new_typhoon(error: ErrorCode) -> Self {
40        Self {
41            error: ErrorType::Typhoon(error),
42            account_name: None,
43        }
44    }
45
46    pub fn new_custom(error: T) -> Self {
47        Self {
48            error: ErrorType::Custom(error),
49            account_name: None,
50        }
51    }
52
53    pub fn with_account(mut self, name: impl ToString) -> Self {
54        self.account_name = Some(name.to_string());
55        self
56    }
57}
58
59impl<T> From<ErrorCode> for Error<T>
60where
61    T: 'static + ToStr + TryFrom<u32>,
62{
63    fn from(value: ErrorCode) -> Self {
64        Error::new_typhoon(value)
65    }
66}
67
68impl<T> From<ProgramError> for Error<T>
69where
70    T: 'static + ToStr + TryFrom<u32>,
71{
72    fn from(value: ProgramError) -> Self {
73        Error::new_solana(value)
74    }
75}
76
77impl<T> From<Error<T>> for ProgramError
78where
79    T: 'static + ToStr + TryFrom<u32> + Into<u32>,
80{
81    fn from(value: Error<T>) -> Self {
82        let program_error = match value.error {
83            ErrorType::Solana(program_error) => {
84                sol_log(program_error.to_str::<CustomError>());
85                program_error
86            }
87            ErrorType::Typhoon(error_code) => {
88                sol_log(error_code.to_str::<ErrorCode>());
89                ProgramError::Custom(error_code.into())
90            }
91            ErrorType::Custom(custom_error) => {
92                sol_log(custom_error.to_str::<T>());
93                ProgramError::Custom(custom_error.into())
94            }
95        };
96        if let Some(account_name) = value.account_name {
97            sol_log(&format!("Account origin: {account_name}"));
98        }
99
100        program_error
101    }
102}