Skip to main content

rust_okx/
error.rs

1//! Error types returned by the crate.
2
3use crate::transport::TransportError;
4#[cfg(feature = "websocket")]
5pub use crate::ws::WsError;
6
7type BoxError = Box<dyn std::error::Error + Send + Sync>;
8
9/// A type alias for [`std::result::Result`] using this crate's [`Error`].
10pub type Result<T> = std::result::Result<T, Error>;
11
12/// Top-level error type.
13///
14/// Wraps [`RestError`] (REST layer) and optionally `WsError` (WebSocket layer).
15///
16/// The enum is [`#[non_exhaustive]`](https://doc.rust-lang.org/reference/attributes/type_system.html)
17/// so new variants can be added without a breaking change.
18#[derive(Debug, thiserror::Error)]
19#[non_exhaustive]
20pub enum Error {
21    /// An error from the REST API layer.
22    #[error(transparent)]
23    Rest(#[from] RestError),
24
25    /// An error from the WebSocket layer.
26    #[cfg(feature = "websocket")]
27    #[error(transparent)]
28    Ws(#[from] WsError),
29}
30
31/// Errors from the REST API layer.
32#[derive(Debug, thiserror::Error)]
33#[non_exhaustive]
34pub enum RestError {
35    /// The underlying HTTP transport failed (connection, TLS, timeout, …).
36    #[error("transport error: {source}")]
37    Transport {
38        /// Finding the position of the error
39        #[from]
40        source: TransportError,
41    },
42
43    /// The HTTP response had a non-success status before the OKX envelope
44    /// could be decoded.
45    #[error("HTTP {status} from {endpoint}")]
46    HttpStatus {
47        /// The endpoint path, e.g. `/api/v5/account/balance`.
48        endpoint: &'static str,
49        /// HTTP response status code.
50        status: http::StatusCode,
51        /// Response body, decoded lossily as UTF-8 for diagnostics.
52        body: String,
53    },
54
55    /// OKX returned a non-zero response code.
56    #[error("OKX API error {code} from {endpoint}: {message}")]
57    Okx {
58        /// The endpoint path.
59        endpoint: &'static str,
60        /// OKX error code (e.g. `"50011"`). Kept as a string deliberately.
61        code: String,
62        /// Human-readable error message from OKX.
63        message: String,
64    },
65
66    /// The response body could not be decoded into the expected model.
67    #[error("failed to decode response from {endpoint}")]
68    Decode {
69        /// The endpoint path.
70        endpoint: &'static str,
71        /// The underlying deserialization error.
72        #[source]
73        source: serde_json::Error,
74    },
75
76    /// The request could not be encoded (query string, JSON body, or headers).
77    #[error("failed to encode request")]
78    Encode {
79        /// The underlying encoding error.
80        #[source]
81        source: BoxError,
82    },
83
84    /// The client was used in an invalid way (e.g. an authenticated endpoint
85    /// was called without credentials).
86    #[error("invalid configuration: {0}")]
87    Configuration(String),
88}