lighter_rust/
error.rs

1use thiserror::Error;
2
3#[derive(Error, Debug)]
4pub enum LighterError {
5    #[error("HTTP request failed: {0}")]
6    Http(#[from] Box<reqwest::Error>),
7
8    #[error("JSON serialization/deserialization failed: {0}")]
9    Json(#[from] serde_json::Error),
10
11    #[error("WebSocket error: {0}")]
12    WebSocket(#[from] Box<tungstenite::Error>),
13
14    #[error("Signing error: {0}")]
15    Signing(String),
16
17    #[error("API error: {status} - {message}")]
18    Api { status: u16, message: String },
19
20    #[error("Invalid configuration: {0}")]
21    Config(String),
22
23    #[error("Authentication failed: {0}")]
24    Auth(String),
25
26    #[error("Rate limit exceeded")]
27    RateLimit,
28
29    #[error("Invalid nonce: {0}")]
30    Nonce(String),
31
32    #[error("Account tier switch not allowed: {0}")]
33    AccountTierSwitch(String),
34
35    #[error("Invalid account state: {0}")]
36    AccountState(String),
37
38    #[error("Order validation failed: {0}")]
39    OrderValidation(String),
40
41    #[error("Unknown error: {0}")]
42    Unknown(String),
43}
44
45pub type Result<T> = std::result::Result<T, LighterError>;
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50
51    #[test]
52    fn test_error_display() {
53        let error = LighterError::Auth("Invalid API key".to_string());
54        assert_eq!(error.to_string(), "Authentication failed: Invalid API key");
55
56        let error = LighterError::RateLimit;
57        assert_eq!(error.to_string(), "Rate limit exceeded");
58
59        let error = LighterError::Api {
60            status: 404,
61            message: "Order not found".to_string(),
62        };
63        assert_eq!(error.to_string(), "API error: 404 - Order not found");
64    }
65
66    #[tokio::test]
67    async fn test_error_from_reqwest() {
68        // This tests the automatic conversion from reqwest::Error
69        let url = "http://invalid-url-that-doesnt-exist-12345.com";
70        let client = reqwest::Client::new();
71        let result = client.get(url).send().await;
72
73        if let Err(e) = result {
74            let lighter_error: LighterError = Box::new(e).into();
75            assert!(matches!(lighter_error, LighterError::Http(_)));
76        }
77    }
78
79    #[test]
80    fn test_error_from_json() {
81        let invalid_json = "{ invalid json }";
82        let result: std::result::Result<serde_json::Value, _> = serde_json::from_str(invalid_json);
83
84        if let Err(e) = result {
85            let lighter_error: LighterError = e.into();
86            assert!(matches!(lighter_error, LighterError::Json(_)));
87        }
88    }
89
90    #[test]
91    fn test_result_type_alias() {
92        fn test_function() -> Result<String> {
93            Ok("success".to_string())
94        }
95
96        let result = test_function();
97        assert!(result.is_ok());
98        assert_eq!(result.unwrap(), "success");
99
100        fn test_error_function() -> Result<String> {
101            Err(LighterError::Unknown("test error".to_string()))
102        }
103
104        let result = test_error_function();
105        assert!(result.is_err());
106    }
107}