1mod error_code;
2mod extension;
3
4use pinocchio::program_error::{ProgramError, ToStr};
5pub use {error_code::*, extension::*};
6
7pub struct Error {
8 error: ProgramError,
9 account_name: Option<String>,
10}
11
12impl Error {
13 pub fn new(error: impl Into<ProgramError>) -> Self {
14 Error {
15 error: error.into(),
16 account_name: None,
17 }
18 }
19
20 pub fn with_account(mut self, name: impl ToString) -> Self {
21 self.account_name = Some(name.to_string());
22 self
23 }
24
25 pub fn account_name(&self) -> Option<&String> {
26 self.account_name.as_ref()
27 }
28}
29
30impl ToStr for Error {
31 fn to_str<E>(&self) -> &'static str
32 where
33 E: 'static + ToStr + TryFrom<u32>,
34 {
35 if let ProgramError::Custom(code) = self.error {
36 if (100..200).contains(&code) {
37 return self.error.to_str::<ErrorCode>();
38 }
39 }
40 self.error.to_str::<E>()
41 }
42}
43
44impl From<ProgramError> for Error {
45 fn from(error: ProgramError) -> Self {
46 Error {
47 error,
48 account_name: None,
49 }
50 }
51}
52
53impl From<ErrorCode> for Error {
54 fn from(value: ErrorCode) -> Self {
55 Error {
56 error: value.into(),
57 account_name: None,
58 }
59 }
60}
61
62impl From<Error> for ProgramError {
63 fn from(value: Error) -> Self {
64 value.error
65 }
66}
67
68#[macro_export]
69macro_rules! impl_error_logger {
70 ($error:ident) => {
71 #[cfg(feature = "logging")]
72 #[cold]
73 fn log_error(error: &ErrorV2) {
74 pinocchio::log::sol_log(error.to_str::<$error>());
75
76 if let Some(account_name) = error.account_name() {
77 pinocchio::log::sol_log(&std::format!("Account origin: {account_name}"));
78 }
79 }
80 };
81}