rust_okx/error.rs
1//! Error types returned by the crate.
2
3use crate::transport::TransportError;
4
5/// A boxed, thread-safe error used as the `source` of opaque variants so that
6/// concrete dependency error types (e.g. `serde_json::Error`) do not leak into
7/// this crate's public API.
8type BoxError = Box<dyn std::error::Error + Send + Sync>;
9
10/// Errors that can occur while making an OKX API request.
11///
12/// The enum is [`#[non_exhaustive]`](https://doc.rust-lang.org/reference/attributes/type_system.html)
13/// so new variants can be added without a breaking change. Downstream code can
14/// match on [`Error::Api`] and inspect the OKX error `code` (kept as a `String`,
15/// since OKX codes are not guaranteed to be parseable integers).
16#[derive(Debug, thiserror::Error)]
17#[non_exhaustive]
18pub enum Error {
19 /// The underlying HTTP transport failed (connection, TLS, timeout, …).
20 #[error("transport error: {0}")]
21 Transport(#[from] TransportError),
22
23 /// The request could not be encoded (query string or JSON body).
24 #[error("failed to encode request: {0}")]
25 Encode(#[source] BoxError),
26
27 /// The response body could not be decoded into the expected model.
28 #[error("failed to decode response: {0}")]
29 Decode(#[source] BoxError),
30
31 /// OKX returned a non-zero response code.
32 #[error("OKX API error {code}: {message}")]
33 Api {
34 /// OKX error code (e.g. `"50011"`). Kept as a string deliberately.
35 code: String,
36 /// Human-readable error message from OKX.
37 message: String,
38 },
39
40 /// The HTTP response had a non-success status before the OKX response
41 /// envelope could be decoded.
42 #[error("HTTP status {status}: {body}")]
43 HttpStatus {
44 /// HTTP response status code.
45 status: http::StatusCode,
46 /// Response body, decoded lossily as UTF-8 for diagnostics.
47 body: String,
48 },
49
50 /// The client was used in an invalid way (e.g. an authenticated endpoint
51 /// was called without credentials).
52 #[error("invalid configuration: {0}")]
53 Configuration(String),
54}
55
56impl Error {
57 /// Construct an [`Error::Encode`] from any boxable error.
58 pub(crate) fn encode(err: impl Into<BoxError>) -> Self {
59 Error::Encode(err.into())
60 }
61
62 /// Construct an [`Error::Decode`] from any boxable error.
63 pub(crate) fn decode(err: impl Into<BoxError>) -> Self {
64 Error::Decode(err.into())
65 }
66}