nautilus_binance/spot/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//! Binance Spot HTTP error types.
17
18use std::fmt::{self, Display};
19
20use nautilus_network::http::error::HttpClientError;
21
22/// Binance Spot HTTP client error type.
23#[derive(Debug)]
24pub enum BinanceSpotHttpError {
25    /// Missing API credentials for authenticated request.
26    MissingCredentials,
27    /// Binance API returned an error response.
28    BinanceError {
29        /// Binance error code.
30        code: i64,
31        /// Error message from Binance.
32        message: String,
33    },
34    /// SBE decode error.
35    SbeDecodeError(SbeDecodeError),
36    /// Request validation error.
37    ValidationError(String),
38    /// Network or connection error.
39    NetworkError(String),
40    /// Request timed out.
41    Timeout(String),
42    /// Request was canceled.
43    Canceled(String),
44    /// Unexpected HTTP status code.
45    UnexpectedStatus {
46        /// HTTP status code.
47        status: u16,
48        /// Response body (hex encoded for SBE).
49        body: String,
50    },
51}
52
53impl Display for BinanceSpotHttpError {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        match self {
56            Self::MissingCredentials => write!(f, "Missing API credentials"),
57            Self::BinanceError { code, message } => {
58                write!(f, "Binance error {code}: {message}")
59            }
60            Self::SbeDecodeError(err) => write!(f, "SBE decode error: {err}"),
61            Self::ValidationError(msg) => write!(f, "Validation error: {msg}"),
62            Self::NetworkError(msg) => write!(f, "Network error: {msg}"),
63            Self::Timeout(msg) => write!(f, "Timeout: {msg}"),
64            Self::Canceled(msg) => write!(f, "Canceled: {msg}"),
65            Self::UnexpectedStatus { status, body } => {
66                write!(f, "Unexpected status {status}: {body}")
67            }
68        }
69    }
70}
71
72impl std::error::Error for BinanceSpotHttpError {}
73
74impl From<SbeDecodeError> for BinanceSpotHttpError {
75    fn from(err: SbeDecodeError) -> Self {
76        Self::SbeDecodeError(err)
77    }
78}
79
80impl From<anyhow::Error> for BinanceSpotHttpError {
81    fn from(err: anyhow::Error) -> Self {
82        Self::NetworkError(err.to_string())
83    }
84}
85
86impl From<HttpClientError> for BinanceSpotHttpError {
87    fn from(err: HttpClientError) -> Self {
88        match err {
89            HttpClientError::TimeoutError(msg) => Self::Timeout(msg),
90            HttpClientError::InvalidProxy(msg) | HttpClientError::ClientBuildError(msg) => {
91                Self::NetworkError(msg)
92            }
93            HttpClientError::Error(msg) => Self::NetworkError(msg),
94        }
95    }
96}
97
98/// Result type for Binance Spot HTTP operations.
99pub type BinanceSpotHttpResult<T> = Result<T, BinanceSpotHttpError>;
100
101/// SBE decode error.
102#[derive(Debug, Clone, PartialEq, Eq)]
103pub enum SbeDecodeError {
104    /// Buffer too short to decode expected data.
105    BufferTooShort { expected: usize, actual: usize },
106    /// Schema ID mismatch.
107    SchemaMismatch { expected: u16, actual: u16 },
108    /// Schema version mismatch.
109    VersionMismatch { expected: u16, actual: u16 },
110    /// Unknown template ID.
111    UnknownTemplateId(u16),
112    /// Group count exceeds safety limit.
113    GroupSizeTooLarge { count: u32, max: u32 },
114    /// Invalid UTF-8 in string field.
115    InvalidUtf8,
116}
117
118impl Display for SbeDecodeError {
119    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
120        match self {
121            Self::BufferTooShort { expected, actual } => {
122                write!(
123                    f,
124                    "Buffer too short: expected {expected} bytes, got {actual}"
125                )
126            }
127            Self::SchemaMismatch { expected, actual } => {
128                write!(f, "Schema ID mismatch: expected {expected}, got {actual}")
129            }
130            Self::VersionMismatch { expected, actual } => {
131                write!(
132                    f,
133                    "Schema version mismatch: expected {expected}, got {actual}"
134                )
135            }
136            Self::UnknownTemplateId(id) => write!(f, "Unknown template ID: {id}"),
137            Self::GroupSizeTooLarge { count, max } => {
138                write!(f, "Group size {count} exceeds maximum {max}")
139            }
140            Self::InvalidUtf8 => write!(f, "Invalid UTF-8 in string field"),
141        }
142    }
143}
144
145impl std::error::Error for SbeDecodeError {}