nautilus_bitmex/websocket/
error.rs1use thiserror::Error;
17use tokio_tungstenite::tungstenite;
18
19#[derive(Debug, Error)]
21pub enum BitmexWsError {
22 #[error("Parsing error: {0}")]
24 ParsingError(String),
25 #[error("BitMEX error {error_name}: {message}")]
27 BitmexError { error_name: String, message: String },
28 #[error("JSON error: {0}")]
30 JsonError(String),
31 #[error("Client error: {0}")]
33 ClientError(String),
34 #[error("Authentication error: {0}")]
36 AuthenticationError(String),
37 #[error("Subscription error: {0}")]
39 SubscriptionError(String),
40 #[error("Tungstenite error: {0}")]
42 TungsteniteError(#[from] tungstenite::Error),
43 #[error("Missing credentials: API authentication required for this operation")]
45 MissingCredentials,
46}
47
48impl From<serde_json::Error> for BitmexWsError {
49 fn from(error: serde_json::Error) -> Self {
50 Self::JsonError(error.to_string())
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use rstest::rstest;
57
58 use super::*;
59
60 #[rstest]
61 fn test_bitmex_ws_error_display() {
62 let error = BitmexWsError::ParsingError("Invalid message format".to_string());
63 assert_eq!(error.to_string(), "Parsing error: Invalid message format");
64
65 let error = BitmexWsError::BitmexError {
66 error_name: "InvalidTopic".to_string(),
67 message: "Unknown subscription topic".to_string(),
68 };
69 assert_eq!(
70 error.to_string(),
71 "BitMEX error InvalidTopic: Unknown subscription topic"
72 );
73
74 let error = BitmexWsError::ClientError("Connection lost".to_string());
75 assert_eq!(error.to_string(), "Client error: Connection lost");
76
77 let error = BitmexWsError::AuthenticationError("Invalid API key".to_string());
78 assert_eq!(error.to_string(), "Authentication error: Invalid API key");
79
80 let error = BitmexWsError::SubscriptionError("Topic not available".to_string());
81 assert_eq!(error.to_string(), "Subscription error: Topic not available");
82
83 let error = BitmexWsError::MissingCredentials;
84 assert_eq!(
85 error.to_string(),
86 "Missing credentials: API authentication required for this operation"
87 );
88 }
89
90 #[rstest]
91 fn test_bitmex_ws_error_from_json_error() {
92 let json_err = serde_json::from_str::<serde_json::Value>("invalid json").unwrap_err();
93 let ws_error: BitmexWsError = json_err.into();
94 assert!(ws_error.to_string().contains("JSON error"));
95 }
96
97 #[rstest]
98 fn test_bitmex_ws_error_from_tungstenite() {
99 use tokio_tungstenite::tungstenite::Error as WsError;
100
101 let tungstenite_err = WsError::ConnectionClosed;
102 let ws_error: BitmexWsError = tungstenite_err.into();
103 assert!(ws_error.to_string().contains("Tungstenite error"));
104 }
105}