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
56impl From<String> for BitmexWsError {
57 fn from(msg: String) -> Self {
58 Self::AuthenticationError(msg)
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use rstest::rstest;
65
66 use super::*;
67
68 #[rstest]
69 fn test_bitmex_ws_error_display() {
70 let error = BitmexWsError::ParsingError("Invalid message format".to_string());
71 assert_eq!(error.to_string(), "Parsing error: Invalid message format");
72
73 let error = BitmexWsError::BitmexError {
74 error_name: "InvalidTopic".to_string(),
75 message: "Unknown subscription topic".to_string(),
76 };
77 assert_eq!(
78 error.to_string(),
79 "BitMEX error InvalidTopic: Unknown subscription topic"
80 );
81
82 let error = BitmexWsError::ClientError("Connection lost".to_string());
83 assert_eq!(error.to_string(), "Client error: Connection lost");
84
85 let error = BitmexWsError::AuthenticationError("Invalid API key".to_string());
86 assert_eq!(error.to_string(), "Authentication error: Invalid API key");
87
88 let error = BitmexWsError::SubscriptionError("Topic not available".to_string());
89 assert_eq!(error.to_string(), "Subscription error: Topic not available");
90
91 let error = BitmexWsError::MissingCredentials;
92 assert_eq!(
93 error.to_string(),
94 "Missing credentials: API authentication required for this operation"
95 );
96 }
97
98 #[rstest]
99 fn test_bitmex_ws_error_from_json_error() {
100 let json_err = serde_json::from_str::<serde_json::Value>("invalid json").unwrap_err();
101 let ws_error: BitmexWsError = json_err.into();
102 assert!(ws_error.to_string().contains("JSON error"));
103 }
104
105 #[rstest]
106 fn test_bitmex_ws_error_from_tungstenite() {
107 use tokio_tungstenite::tungstenite::Error as WsError;
108
109 let tungstenite_err = WsError::ConnectionClosed;
110 let ws_error: BitmexWsError = tungstenite_err.into();
111 assert!(ws_error.to_string().contains("Tungstenite error"));
112 }
113}