surfpool_core/
error.rs

1use std::{future::Future, pin::Pin};
2
3use crossbeam_channel::TrySendError;
4use serde::Serialize;
5use serde_json::json;
6
7use jsonrpc_core::{Error, Result};
8use solana_pubkey::Pubkey;
9
10pub type SurfpoolResult<T> = std::result::Result<T, SurfpoolError>;
11
12#[derive(Debug, Clone)]
13pub struct SurfpoolError(Error);
14
15impl From<SurfpoolError> for String {
16    fn from(e: SurfpoolError) -> Self {
17        e.0.to_string()
18    }
19}
20
21impl From<SurfpoolError> for Error {
22    fn from(e: SurfpoolError) -> Self {
23        e.0
24    }
25}
26
27impl std::error::Error for SurfpoolError {}
28
29impl std::fmt::Display for SurfpoolError {
30    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
31        let Error {
32            code,
33            message,
34            data,
35        } = &self.0;
36
37        let core = if code.description().eq(message) {
38            format!("{}", code.description())
39        } else {
40            format!("{}: {}", code.description(), message)
41        };
42
43        if let Some(data_value) = data {
44            write!(f, "{}: {}", core, data_value.to_string().as_str())
45        } else {
46            write!(f, "{}", core)
47        }
48    }
49}
50
51impl<T> From<SurfpoolError> for Pin<Box<dyn Future<Output = Result<T>> + Send>> {
52    fn from(e: SurfpoolError) -> Self {
53        Box::pin(async move { Err(e.into()) })
54    }
55}
56
57impl<T> Into<SurfpoolError> for TrySendError<T> {
58    fn into(self) -> SurfpoolError {
59        SurfpoolError::from_try_send_error(self)
60    }
61}
62
63impl SurfpoolError {
64    pub fn from_try_send_error<T>(e: TrySendError<T>) -> Self {
65        let mut error = Error::internal_error();
66        error.data = Some(json!(format!(
67            "Failed to send command on channel: {}",
68            e.to_string()
69        )));
70        Self(error)
71    }
72
73    pub fn no_locker() -> Self {
74        let mut error = Error::internal_error();
75        error.data = Some(json!("Failed to access internal SVM state"));
76        Self(error)
77    }
78
79    pub fn set_account<T>(pubkey: Pubkey, e: T) -> Self
80    where
81        T: ToString,
82    {
83        let mut error = Error::internal_error();
84        error.data = Some(json!(format!(
85            "Failed to set account {} in remote: {}",
86            pubkey,
87            e.to_string()
88        )));
89        Self(error)
90    }
91    pub fn get_account<T>(pubkey: Pubkey, e: T) -> Self
92    where
93        T: ToString,
94    {
95        let mut error = Error::internal_error();
96        error.data = Some(json!(format!(
97            "Failed to fetch account {} from remote: {}",
98            pubkey,
99            e.to_string()
100        )));
101        Self(error)
102    }
103
104    pub fn get_multiple_accounts<T>(e: T) -> Self
105    where
106        T: ToString,
107    {
108        let mut error = Error::internal_error();
109        error.data = Some(json!(format!(
110            "Failed to fetch accounts from remote: {}",
111            e.to_string()
112        )));
113        Self(error)
114    }
115
116    pub fn invalid_pubkey<D>(pubkey: &str, data: D) -> Self
117    where
118        D: Serialize,
119    {
120        let mut error = Error::invalid_params(format!("Invalid pubkey {pubkey}"));
121        error.data = Some(json!(data));
122        Self(error)
123    }
124
125    pub fn invalid_signature<D>(signature: &str, data: D) -> Self
126    where
127        D: Serialize,
128    {
129        let mut error = Error::invalid_params(format!("Invalid signature {signature}"));
130        error.data = Some(json!(data));
131        Self(error)
132    }
133}