longportwhale/
error.rs

1use longportwhale_httpcli::HttpClientError;
2use longportwhale_wscli::WsClientError;
3
4/// LongPort OpenAPI SDK error type
5#[derive(Debug, thiserror::Error)]
6pub enum Error {
7    /// Decode Protobuf error
8    #[error(transparent)]
9    DecodeProtobuf(#[from] prost::DecodeError),
10
11    /// Decode JSON error
12    #[error(transparent)]
13    DecodeJSON(#[from] serde_json::Error),
14
15    /// Parse field
16    #[error("parse field: {name}: {error}")]
17    ParseField {
18        /// Field name
19        name: &'static str,
20
21        /// Error detail
22        error: String,
23    },
24
25    /// Unknown command
26    #[error("unknown command: {0}")]
27    UnknownCommand(
28        /// Command code
29        u8,
30    ),
31
32    /// Invalid security symbol
33    #[error("invalid security symbol: {symbol}")]
34    InvalidSecuritySymbol {
35        /// Security symbol
36        symbol: String,
37    },
38
39    /// HTTP client error
40    #[error(transparent)]
41    HttpClient(#[from] HttpClientError),
42
43    /// Websocket client error
44    #[error(transparent)]
45    WsClient(#[from] WsClientError),
46
47    /// Blocking error
48    #[cfg(feature = "blocking")]
49    #[error(transparent)]
50    Blocking(#[from] crate::blocking::BlockingError),
51}
52
53impl Error {
54    /// Consumes this error and returns a simple error
55    pub fn into_simple_error(self) -> SimpleError {
56        match self {
57            Error::HttpClient(HttpClientError::OpenApi {
58                code,
59                message,
60                trace_id,
61            }) => SimpleError::Response {
62                code: code as i64,
63                message,
64                trace_id,
65            },
66            Error::WsClient(WsClientError::ResponseError {
67                detail: Some(detail),
68                ..
69            }) => SimpleError::Response {
70                code: detail.code as i64,
71                message: detail.msg,
72                trace_id: String::new(),
73            },
74            Error::DecodeProtobuf(_)
75            | Error::DecodeJSON(_)
76            | Error::InvalidSecuritySymbol { .. }
77            | Error::ParseField { .. }
78            | Error::UnknownCommand(_)
79            | Error::HttpClient(_)
80            | Error::WsClient(_) => SimpleError::Other(self.to_string()),
81            #[cfg(feature = "blocking")]
82            Error::Blocking(_) => SimpleError::Other(self.to_string()),
83        }
84    }
85}
86
87/// LongPort OpenAPI SDK result type
88pub type Result<T> = ::std::result::Result<T, Error>;
89
90/// Simple error type
91#[derive(Debug, thiserror::Error)]
92pub enum SimpleError {
93    /// Response error
94    #[error("response error: code={code} message={message}")]
95    Response {
96        /// Error code
97        code: i64,
98        /// Error message
99        message: String,
100        /// Trace id
101        trace_id: String,
102    },
103    /// Other error
104    #[error("other error: {0}")]
105    Other(String),
106}
107
108impl From<Error> for SimpleError {
109    #[inline]
110    fn from(err: Error) -> Self {
111        err.into_simple_error()
112    }
113}
114
115impl SimpleError {
116    /// Returns the error code
117    pub fn code(&self) -> Option<i64> {
118        match self {
119            SimpleError::Response { code, .. } => Some(*code),
120            SimpleError::Other(_) => None,
121        }
122    }
123
124    /// Returns the error message
125    pub fn message(&self) -> &str {
126        match self {
127            SimpleError::Response { message, .. } => message.as_str(),
128            SimpleError::Other(message) => message.as_str(),
129        }
130    }
131
132    /// Returns trace id if have
133    pub fn trace_id(&self) -> &str {
134        match self {
135            SimpleError::Response { trace_id, .. } => trace_id.as_str(),
136            SimpleError::Other(..) => "",
137        }
138    }
139}