use thiserror::Error;
use tokio_tungstenite::tungstenite;
#[derive(Debug, Error)]
pub enum BitmexWsError {
#[error("Parsing error: {0}")]
ParsingError(String),
#[error("BitMEX error {error_name}: {message}")]
BitmexError { error_name: String, message: String },
#[error("JSON error: {0}")]
JsonError(String),
#[error("Client error: {0}")]
ClientError(String),
#[error("Authentication error: {0}")]
AuthenticationError(String),
#[error("Subscription error: {0}")]
SubscriptionError(String),
#[error("Tungstenite error: {0}")]
TungsteniteError(#[from] tungstenite::Error),
#[error("Missing credentials: API authentication required for this operation")]
MissingCredentials,
}
impl From<serde_json::Error> for BitmexWsError {
fn from(error: serde_json::Error) -> Self {
Self::JsonError(error.to_string())
}
}
impl From<String> for BitmexWsError {
fn from(msg: String) -> Self {
Self::AuthenticationError(msg)
}
}
#[cfg(test)]
mod tests {
use rstest::rstest;
use super::*;
#[rstest]
fn test_bitmex_ws_error_display() {
let error = BitmexWsError::ParsingError("Invalid message format".to_string());
assert_eq!(error.to_string(), "Parsing error: Invalid message format");
let error = BitmexWsError::BitmexError {
error_name: "InvalidTopic".to_string(),
message: "Unknown subscription topic".to_string(),
};
assert_eq!(
error.to_string(),
"BitMEX error InvalidTopic: Unknown subscription topic"
);
let error = BitmexWsError::ClientError("Connection lost".to_string());
assert_eq!(error.to_string(), "Client error: Connection lost");
let error = BitmexWsError::AuthenticationError("Invalid API key".to_string());
assert_eq!(error.to_string(), "Authentication error: Invalid API key");
let error = BitmexWsError::SubscriptionError("Topic not available".to_string());
assert_eq!(error.to_string(), "Subscription error: Topic not available");
let error = BitmexWsError::MissingCredentials;
assert_eq!(
error.to_string(),
"Missing credentials: API authentication required for this operation"
);
}
#[rstest]
fn test_bitmex_ws_error_from_json_error() {
let json_err = serde_json::from_str::<serde_json::Value>("invalid json").unwrap_err();
let ws_error: BitmexWsError = json_err.into();
assert!(ws_error.to_string().contains("JSON error"));
}
#[rstest]
fn test_bitmex_ws_error_from_tungstenite() {
use tokio_tungstenite::tungstenite::Error as WsError;
let tungstenite_err = WsError::ConnectionClosed;
let ws_error: BitmexWsError = tungstenite_err.into();
assert!(ws_error.to_string().contains("Tungstenite error"));
}
}