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}