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 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}