brokapi_bybit_protocol/error.rs
1//! Errors of the Bybit protocol layer.
2//!
3//! [`BybitApiError`] is what every client method returns. The connector crate maps it to the broker-independent error
4//! of `brokapi-core`.
5
6use thiserror::Error;
7
8/// An error of a call to Bybit.
9#[derive(Error, Debug)]
10pub enum BybitApiError {
11 /// The transport failed, or the server answered a status that is not a success.
12 #[error("HTTP error: {message}")]
13 Http {
14 /// The HTTP status, when the server answered.
15 status: Option<u16>,
16 /// What went wrong.
17 message: String,
18 },
19
20 /// The server answered HTTP 200 with a non-zero `retCode`: a refusal of the request itself.
21 #[error("API error {code}: {message}")]
22 Api {
23 /// The `retCode`.
24 code: i64,
25 /// The `retMsg`.
26 message: String,
27 },
28
29 /// The WebSocket failed.
30 #[error("WebSocket error: {message}")]
31 Ws {
32 /// What went wrong.
33 message: String,
34 },
35
36 /// The key pair was refused (HTTP 401, or a `retCode` of authentication: 10003, 10004, 10005, 10007, 10010).
37 #[error("authorization error: {message}")]
38 Auth {
39 /// The reason the exchange gave.
40 message: String,
41 },
42
43 /// The answer is a success but is not the JSON that was expected.
44 #[error("parse error: {0}")]
45 Parse(String),
46
47 /// The request rate limit: HTTP 429, or `retCode` 10006.
48 #[error("rate limit exceeded")]
49 RateLimitExceeded,
50
51 /// A subscription could not be made.
52 #[error("subscription error: {message}")]
53 Subscription {
54 /// What went wrong.
55 message: String,
56 },
57}
58
59impl BybitApiError {
60 /// The `retCode` of a refusal, if this is one.
61 pub fn code(&self) -> Option<i64> {
62 match self {
63 BybitApiError::Api { code, .. } => Some(*code),
64 _ => None,
65 }
66 }
67}
68
69impl From<reqwest::Error> for BybitApiError {
70 fn from(err: reqwest::Error) -> Self {
71 BybitApiError::Http {
72 status: err.status().map(|s| s.as_u16()),
73 message: err.to_string(),
74 }
75 }
76}
77
78impl From<serde_json::Error> for BybitApiError {
79 fn from(err: serde_json::Error) -> Self {
80 BybitApiError::Parse(err.to_string())
81 }
82}
83
84/// The `retCode`s that mean the key pair, its rights or its IP binding are wrong.
85pub fn is_auth_code(code: i64) -> bool {
86 matches!(code, 10003 | 10004 | 10005 | 10007 | 10010 | 33004)
87}