nautilus_deribit/http/
error.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2025 Nautech Systems Pty Ltd. All rights reserved.
3//  https://nautechsystems.io
4//
5//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6//  You may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16//! Deribit HTTP client error types.
17
18use std::fmt;
19
20/// Represents HTTP client errors for the Deribit adapter.
21#[derive(Debug, Clone)]
22pub enum DeribitHttpError {
23    /// Missing API credentials
24    MissingCredentials,
25    /// Deribit-specific error with code and message
26    DeribitError { error_code: i64, message: String },
27    /// JSON serialization/deserialization error
28    JsonError(String),
29    /// Input validation error
30    ValidationError(String),
31    /// Network-related error
32    NetworkError(String),
33    /// Request timeout
34    Timeout(String),
35    /// Request canceled
36    Canceled(String),
37    /// Unexpected HTTP status
38    UnexpectedStatus { status: u16, body: String },
39}
40
41impl fmt::Display for DeribitHttpError {
42    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43        match self {
44            Self::MissingCredentials => write!(f, "Missing API credentials"),
45            Self::DeribitError {
46                error_code,
47                message,
48            } => write!(f, "Deribit error {error_code}: {message}"),
49            Self::JsonError(msg) => write!(f, "JSON error: {msg}"),
50            Self::ValidationError(msg) => write!(f, "Validation error: {msg}"),
51            Self::NetworkError(msg) => write!(f, "Network error: {msg}"),
52            Self::Timeout(msg) => write!(f, "Timeout: {msg}"),
53            Self::Canceled(msg) => write!(f, "Canceled: {msg}"),
54            Self::UnexpectedStatus { status, body } => {
55                write!(f, "Unexpected status {status}: {body}")
56            }
57        }
58    }
59}
60
61impl std::error::Error for DeribitHttpError {}
62
63impl From<serde_json::Error> for DeribitHttpError {
64    fn from(error: serde_json::Error) -> Self {
65        Self::JsonError(error.to_string())
66    }
67}
68
69impl From<anyhow::Error> for DeribitHttpError {
70    fn from(error: anyhow::Error) -> Self {
71        Self::NetworkError(error.to_string())
72    }
73}
74
75impl DeribitHttpError {
76    /// Maps a JSON-RPC error to the appropriate error variant.
77    ///
78    /// Standard JSON-RPC error codes (-32xxx) are mapped to `ValidationError`,
79    /// while Deribit-specific error codes are mapped to `DeribitError`.
80    ///
81    /// # Arguments
82    ///
83    /// * `error_code` - The JSON-RPC error code
84    /// * `message` - The error message
85    /// * `data` - Optional additional error data
86    pub fn from_jsonrpc_error(
87        error_code: i64,
88        message: String,
89        data: Option<serde_json::Value>,
90    ) -> Self {
91        match error_code {
92            // JSON-RPC 2.0 standard error codes
93            -32700 => Self::ValidationError(format!("Parse error: {message}")),
94            -32600 => Self::ValidationError(format!("Invalid request: {message}")),
95            -32601 => Self::ValidationError(format!("Method not found: {message}")),
96            -32602 => {
97                // Try to extract parameter details from data field
98                let detail = data
99                    .as_ref()
100                    .and_then(|d| d.as_object())
101                    .and_then(|obj| {
102                        let param = obj.get("param")?.as_str()?;
103                        let reason = obj.get("reason")?.as_str()?;
104                        Some(format!(" (parameter '{param}': {reason})"))
105                    })
106                    .unwrap_or_default();
107                Self::ValidationError(format!("Invalid params: {message}{detail}"))
108            }
109            -32603 => Self::ValidationError(format!("Internal error: {message}")),
110            // All other error codes are Deribit-specific
111            _ => Self::DeribitError {
112                error_code,
113                message,
114            },
115        }
116    }
117}