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