1use serde_json::Error as SerdeJsonError;
2use std::error::Error as StdError;
3use std::fmt;
4use std::fmt::Debug;
5use std::sync::Arc;
6
7type ParentError = Arc<dyn StdError + Send + Sync + 'static>;
8
9#[derive(Clone, Debug)]
11pub enum SbError {
12 Generic,
14 Message(&'static str),
15 CustomMessage(String),
16 CustomError {
17 message: String,
18 source: ParentError,
19 },
20 Unexpected,
21 EnvVariableMissing(String),
23 InvalidKeypairFile,
24 KeyParseError,
25 CheckSizeError,
26
27 IoError(ParentError),
28
29 SgxError,
31 SgxWriteError,
32
33 NetworkError,
35
36 QuoteParseError,
38 InvalidQuoteError,
39
40 QvnError(Arc<String>),
42
43 DockerError,
45 DockerFetchError,
46 FunctionImageTooBigError,
47 ContainerErrorMessage(String),
48 ContainerError(ParentError),
49 ContainerStartError(ParentError),
50 ContainerCreateError(ParentError),
51 ContainerNeedsUpdate,
52 ContainerResultParseError,
54 AttachError,
55 ContainerTimeout,
56 ContainerActive,
57 ContainerBackoff(u64),
58 FunctionErrorCountExceeded(u32),
59
60 FunctionResultParseError,
62 IllegalFunctionOutput,
63 FunctionVerifyFailure,
64 FunctionResultIllegalAccount,
65 FunctionResultAccountsMismatch,
66 FunctionResultInvalidData,
67 FunctionResultInvalidPid,
68 FunctionResultEmptyInstructions,
69
70 TxFailure,
72 TxCompileErr,
73 TxDeserializationError,
74 QvnTxSendFailure,
75 InvalidInstructionError,
76
77 InvalidChain,
79 AnchorParse,
80 AnchorParseError,
81 EvmError,
82
83 IpfsParseError,
85 IpfsNetworkError,
86 HeartbeatRoutineFailure,
87 EventListenerRoutineFailure,
88 DecryptError,
89 ParseError,
90 MrEnclaveMismatch,
91 FunctionResultIxIncorrectTargetChain,
92 InvalidSignature,
93
94 SolanaFetchError(String),
97 SolanaBlockhashError,
99 SolanaBlockhashFetchError(ParentError),
101 SolanaPayerMismatch(String, String),
104 SolanaPayerSignerMissing(String),
105 SolanaMissingSigner(String),
107 SolanaSignError(ParentError, String),
108 SolanaInstructionsEmpty,
109 SolanaInstructionOverflow,
110 FunctionResultIxMissingDiscriminator,
111 FunctionResultError(&'static str),
112 FunctionResultIxError(&'static str),
113 FunctionResultFailoverError(u8, ParentError),
115 FunctionResultNonRetryableError(ParentError),
117
118 AccountNotFound,
119}
120
121impl fmt::Display for SbError {
122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123 match self {
124 SbError::EnvVariableMissing(message) => {
125 write!(f, "Env variable missing: {}", message.as_str())
126 }
127 SbError::Message(message) => write!(f, "error: {}", message),
128 SbError::CustomMessage(message) => write!(f, "error: {}", message.as_str()),
129 SbError::CustomError {
130 message, source, ..
131 } => write!(f, "error: {} - {:?}", message.as_str(), source),
132 SbError::FunctionResultError(message) => {
133 write!(f, "error: FunctionResultError - {}", message)
134 }
135 SbError::FunctionResultIxError(message) => {
136 write!(f, "error: FunctionResultIxError - {}", message)
137 }
138 SbError::FunctionResultFailoverError(code, source) => {
139 write!(
140 f,
141 "error: FunctionResultFailoverError ({}) - {:?}",
142 code, source
143 )
144 }
145 SbError::FunctionResultNonRetryableError(source) => {
146 write!(f, "error: FunctionResultNonRetryableError - {:?}", source)
147 }
148 SbError::SolanaPayerMismatch(expected, actual) => {
149 write!(
150 f,
151 "error: SolanaPayerMismatch - expected: {}, actual: {}",
152 expected, actual
153 )
154 }
155 SbError::SolanaMissingSigner(missing_signer) => {
156 write!(f, "error: Missing required signer: {}", missing_signer)
157 }
158 SbError::SolanaInstructionsEmpty => write!(
159 f,
160 "error: The attempted action requires at least one instruction but none were provided"
161 ),
162 SbError::SolanaInstructionOverflow => write!(
163 f,
164 "error: The transaction exceeded the maximum number of instructions (10)"
165 ),
166 SbError::SolanaPayerSignerMissing(payer) => write!(
167 f,
168 "error: The payer keypair is missing from the provided signers: {}",
169 payer
170 ),
171 SbError::SolanaBlockhashFetchError(source) => write!(
172 f,
173 "error: Failed to fetch blockhash from the cluster. Please try again. - {:?}", source
174 ),
175 _ => write!(f, "{:#?}", self),
177 }
178 }
179}
180
181impl From<&str> for SbError {
182 fn from(error: &str) -> Self {
183 SbError::CustomMessage(error.to_string())
184 }
185}
186impl From<String> for SbError {
187 fn from(error: String) -> Self {
188 SbError::CustomMessage(error)
189 }
190}
191
192impl From<hex::FromHexError> for SbError {
193 fn from(error: hex::FromHexError) -> Self {
194 SbError::CustomError {
195 message: "hex error".to_string(),
196 source: Arc::new(error),
197 }
198 }
199}
200
201impl StdError for SbError {
202 fn source(&self) -> Option<&(dyn StdError + 'static)> {
203 match self {
204 SbError::CustomError { source, .. } => Some(source.as_ref()), SbError::ContainerError(source) => Some(source.as_ref()),
206 SbError::ContainerStartError(source) => Some(source.as_ref()),
207 SbError::SolanaSignError(source, ..) => Some(source.as_ref()),
208 SbError::FunctionResultFailoverError(_code, source, ..) => Some(source.as_ref()),
209 SbError::FunctionResultNonRetryableError(source, ..) => Some(source.as_ref()),
210 _ => None,
211 }
212 }
213}
214
215impl From<SerdeJsonError> for SbError {
216 fn from(error: SerdeJsonError) -> Self {
217 SbError::CustomError {
218 message: "serde_json error".to_string(),
219 source: Arc::new(error),
220 }
221 }
222}
223
224impl From<std::io::Error> for SbError {
225 fn from(val: std::io::Error) -> Self {
226 SbError::IoError(std::sync::Arc::new(val))
227 }
228}
229
230#[cfg(test)]
231mod tests {
232 use super::*;
233
234 #[test]
235 fn display_generic() {
236 let error = SbError::Generic;
237 assert_eq!(format!("{}", error), "Generic");
238 }
239
240 #[test]
241 fn display_custom_message() {
242 let error = SbError::CustomMessage("my custom message".to_string());
243 assert_eq!(format!("{}", error), "error: my custom message");
244 }
245
246 #[test]
247 fn display_env_variable_missing() {
248 let error = SbError::EnvVariableMissing("MY_ENV_VAR".to_string());
249 assert_eq!(format!("{}", error), "Env variable missing: MY_ENV_VAR");
250 }
251
252 #[test]
253 fn from_str() {
254 let error: SbError = "my custom message".into();
255 assert_eq!(format!("{}", error), "error: my custom message");
256 }
257
258 #[test]
259 fn from_hex_error() {
260 let hex_error = hex::FromHexError::OddLength;
261 let error: SbError = hex_error.into();
262 assert_eq!(format!("{}", error), "error: hex error - OddLength");
263 }
264
265 #[test]
266 fn from_serde_json_error() {
267 let json = "\"";
268 let serde_json_error = serde_json::from_str::<serde_json::Value>(json).unwrap_err();
269 let error: SbError = serde_json_error.into();
270 assert!(format!("{}", error).starts_with("error: serde_json error - "));
271 }
272}