deriv_api/
error.rs

1use thiserror::Error;
2
3#[derive(Error, Debug)]
4pub enum DerivError {
5    #[error("WebSocket connection error: {0}")]
6    WebSocketError(#[from] tokio_tungstenite::tungstenite::Error),
7
8    #[error("URL parsing error: {0}")]
9    UrlError(#[from] url::ParseError),
10
11    #[error("JSON serialization error: {0}")]
12    SerializationError(#[from] serde_json::Error),
13
14    #[error("Invalid schema: {0}")]
15    InvalidSchema(String),
16
17    #[error("Invalid app ID: {0}")]
18    InvalidAppId(i32),
19
20    #[error("Invalid language code: {0}")]
21    InvalidLanguage(String),
22
23    #[error("Connection closed")]
24    ConnectionClosed,
25
26    #[error("Empty subscription ID")]
27    EmptySubscriptionId,
28    
29    #[error("Subscription error: {0}")]
30    SubscriptionError(String),
31
32    #[error("API error: {code} - {message}")]
33    ApiError {
34        code: String,
35        message: String,
36        details: Option<serde_json::Value>,
37    },
38
39    #[error("Request timeout")]
40    Timeout,
41}
42
43pub type Result<T> = std::result::Result<T, DerivError>;
44
45// API Error response structure
46#[derive(Debug, serde::Deserialize)]
47pub(crate) struct ApiErrorResponse {
48    pub error: ApiErrorDetails,
49}
50
51#[derive(Debug, serde::Deserialize)]
52pub(crate) struct ApiErrorDetails {
53    pub code: String,
54    pub message: String,
55    #[serde(default)]
56    pub details: Option<serde_json::Value>,
57}
58
59impl From<ApiErrorDetails> for DerivError {
60    fn from(error: ApiErrorDetails) -> Self {
61        DerivError::ApiError {
62            code: error.code,
63            message: error.message,
64            details: error.details,
65        }
66    }
67}
68
69pub(crate) fn parse_error(raw_response: &[u8]) -> Result<()> {
70    let response: serde_json::Value = serde_json::from_slice(raw_response)?;
71
72    if let Some(error) = response.get("error") {
73        let error_details: ApiErrorDetails = serde_json::from_value(error.clone())?;
74        return Err(error_details.into());
75    }
76
77    Ok(())
78}