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}