1#![no_std]
2
3mod error_code;
4mod extension;
5
6use pinocchio::program_error::{ProgramError, ToStr};
7pub use {error_code::*, extension::*};
8
9pub struct Error {
10 error: ProgramError,
11 account_name: Option<&'static str>,
12}
13
14impl Error {
15 #[inline(always)]
16 pub fn new(error: impl Into<ProgramError>) -> Self {
17 Error {
18 error: error.into(),
19 account_name: None,
20 }
21 }
22
23 #[inline(always)]
24 pub fn with_account(mut self, name: &'static str) -> Self {
25 self.account_name = Some(name);
26 self
27 }
28
29 #[inline(always)]
30 pub fn account_name(&self) -> Option<&str> {
31 self.account_name
32 }
33}
34
35impl ToStr for Error {
36 fn to_str<E>(&self) -> &'static str
37 where
38 E: 'static + ToStr + TryFrom<u32>,
39 {
40 if let ProgramError::Custom(code) = self.error {
41 if (100..200).contains(&code) {
42 return self.error.to_str::<ErrorCode>();
43 }
44 }
45 self.error.to_str::<E>()
46 }
47}
48
49impl From<ProgramError> for Error {
50 #[inline(always)]
51 fn from(error: ProgramError) -> Self {
52 Error {
53 error,
54 account_name: None,
55 }
56 }
57}
58
59impl From<ErrorCode> for Error {
60 #[inline(always)]
61 fn from(value: ErrorCode) -> Self {
62 Error {
63 error: value.into(),
64 account_name: None,
65 }
66 }
67}
68
69impl From<Error> for ProgramError {
70 #[inline(always)]
71 fn from(value: Error) -> Self {
72 value.error
73 }
74}
75
76#[macro_export]
77macro_rules! impl_error_logger {
78 ($error:ident) => {
79 #[cfg(feature = "logging")]
80 #[cold]
81 fn log_error(error: &Error) {
82 pinocchio::log::sol_log(error.to_str::<$error>());
83 if let Some(account_name) = error.account_name() {
84 let mut buffer = [bytes::UNINIT_BYTE; 50];
85 let total_len = core::cmp::min(account_name.len() + 16, 50);
86 bytes::write_bytes(&mut buffer[..16], b"Account origin: ");
87 bytes::write_bytes(&mut buffer[16..total_len], account_name.as_bytes());
88 pinocchio::log::sol_log(unsafe {
89 core::str::from_utf8_unchecked(core::slice::from_raw_parts(
90 buffer.as_ptr() as _,
91 total_len,
92 ))
93 });
94 }
95 }
96 };
97}