bybit/models/return_codes/
general.rs

1use crate::prelude::*;
2
3/// Enum representing Bybit API V5 General return error/codes.
4///
5/// See: https://bybit-exchange.github.io/docs/v5/error#general-error-codes
6#[derive(Clone, Copy, PartialEq, Eq, Hash, Display, derive_more::Debug, derive_more::From)]
7#[repr(i32)]
8#[display("{} - {}", *self as i32, self.message())]
9pub enum GeneralCode {
10    /// Invalid parameter(s).
11    InvalidParameters = 10001,
12
13    /// Invalid request: server error or request timeout.
14    InvalidRequest = 10002,
15
16    /// API key is invalid.
17    InvalidApiKey = 10003,
18
19    /// Signature error.
20    SignatureError = 10004,
21
22    /// Permission denied.
23    PermissionDenied = 10005,
24
25    /// Too many visits, exceeding IP limit.
26    TooManyVisits = 10006,
27
28    /// Unmatched IP: API key not bound to this IP.
29    UnmatchedIp = 10010,
30
31    /// Request header `bybit-agent` is empty or invalid.
32    InvalidAgentHeader = 10014,
33
34    /// Timestamp is expired or there is a clock skew.
35    TimestampError = 10017,
36
37    /// Futures/Options symbol does not exist.
38    SymbolNotExist = 10021,
39
40    /// Symbol is not trading.
41    SymbolNotTrading = 10022,
42
43    /// Invalid JSON format.
44    InvalidJsonFormat = 100400,
45
46    /// Invalid category.
47    InvalidCategory = 100401,
48
49    /// Internal server error.
50    InternalServerError = 100500,
51
52    /// Invalid account type.
53    InvalidAccountType = 100600,
54
55    /// Insufficient balance in account.
56    InsufficientBalance = 100601,
57
58    /// Invalid sub-account name.
59    InvalidSubAccountName = 100602,
60
61    /// Sub-account does not exist.
62    SubAccountNotExist = 100603,
63
64    /// Master account does not exist.
65    MasterAccountNotExist = 100604,
66
67    /// Failed to create sub-account.
68    SubAccountCreationFailed = 100605,
69
70    /// Sub-account already exists.
71    SubAccountAlreadyExists = 100606,
72
73    /// Invalid API key permission.
74    InvalidApiKeyPermission = 100607,
75
76    /// Failed to update API key.
77    ApiKeyUpdateFailed = 100608,
78
79    /// API key is disabled.
80    ApiKeyDisabled = 100609,
81
82    /// Failed to delete API key.
83    ApiKeyDeletionFailed = 100610,
84
85    /// Invalid batch order request: too many orders or other issues.
86    InvalidBatchOrder = 100611,
87
88    /// Sub-account is frozen.
89    SubAccountFrozen = 100612,
90
91    /// Sub-account permission error.
92    SubAccountPermissionError = 100613,
93
94    /// Master account is frozen.
95    MasterAccountFrozen = 100614,
96
97    /// Master-sub relationship already exists.
98    MasterSubRelationshipExists = 100615,
99}
100
101impl GeneralCode {
102    /// Converts an error code (as i32) to a GeneralError variant.
103    /// Returns None if the code doesn't match any variant.
104    pub fn from_code<T>(code: T) -> Option<Self>
105    where
106        T: Into<i32> + Copy,
107    {
108        let code = code.into();
109        match code {
110            10001 => Some(Self::InvalidParameters),
111            10002 => Some(Self::InvalidRequest),
112            10003 => Some(Self::InvalidApiKey),
113            10004 => Some(Self::SignatureError),
114            10005 => Some(Self::PermissionDenied),
115            10006 => Some(Self::TooManyVisits),
116            10010 => Some(Self::UnmatchedIp),
117            10014 => Some(Self::InvalidAgentHeader),
118            10017 => Some(Self::TimestampError),
119            10021 => Some(Self::SymbolNotExist),
120            10022 => Some(Self::SymbolNotTrading),
121            100400 => Some(Self::InvalidJsonFormat),
122            100401 => Some(Self::InvalidCategory),
123            100500 => Some(Self::InternalServerError),
124            100600 => Some(Self::InvalidAccountType),
125            100601 => Some(Self::InsufficientBalance),
126            100602 => Some(Self::InvalidSubAccountName),
127            100603 => Some(Self::SubAccountNotExist),
128            100604 => Some(Self::MasterAccountNotExist),
129            100605 => Some(Self::SubAccountCreationFailed),
130            100606 => Some(Self::SubAccountAlreadyExists),
131            100607 => Some(Self::InvalidApiKeyPermission),
132            100608 => Some(Self::ApiKeyUpdateFailed),
133            100609 => Some(Self::ApiKeyDisabled),
134            100610 => Some(Self::ApiKeyDeletionFailed),
135            100611 => Some(Self::InvalidBatchOrder),
136            100612 => Some(Self::SubAccountFrozen),
137            100613 => Some(Self::SubAccountPermissionError),
138            100614 => Some(Self::MasterAccountFrozen),
139            100615 => Some(Self::MasterSubRelationshipExists),
140            _ => None,
141        }
142    }
143
144    /// Returns the error message associated with the error code.
145    pub fn message(&self) -> &'static str {
146        match self {
147            Self::InvalidParameters => "Invalid parameter(s).",
148            Self::InvalidRequest => "Invalid request: server error or request timeout.",
149            Self::InvalidApiKey => "API key is invalid.",
150            Self::SignatureError => "Signature error.",
151            Self::PermissionDenied => "Permission denied.",
152            Self::TooManyVisits => "Too many visits, exceeding IP limit.",
153            Self::UnmatchedIp => "Unmatched IP: API key not bound to this IP.",
154            Self::InvalidAgentHeader => "Request header `bybit-agent` is empty or invalid.",
155            Self::TimestampError => "Timestamp is expired or there is a clock skew.",
156            Self::SymbolNotExist => "Futures/Options symbol does not exist.",
157            Self::SymbolNotTrading => "Symbol is not trading.",
158            Self::InvalidJsonFormat => "Invalid JSON format.",
159            Self::InvalidCategory => "Invalid category.",
160            Self::InternalServerError => "Internal server error.",
161            Self::InvalidAccountType => "Invalid account type.",
162            Self::InsufficientBalance => "Insufficient balance in account.",
163            Self::InvalidSubAccountName => "Invalid sub-account name.",
164            Self::SubAccountNotExist => "Sub-account does not exist.",
165            Self::MasterAccountNotExist => "Master account does not exist.",
166            Self::SubAccountCreationFailed => "Failed to create sub-account.",
167            Self::SubAccountAlreadyExists => "Sub-account already exists.",
168            Self::InvalidApiKeyPermission => "Invalid API key permission.",
169            Self::ApiKeyUpdateFailed => "Failed to update API key.",
170            Self::ApiKeyDisabled => "API key is disabled.",
171            Self::ApiKeyDeletionFailed => "Failed to delete API key.",
172            Self::InvalidBatchOrder => {
173                "Invalid batch order request: too many orders or other issues."
174            }
175            Self::SubAccountFrozen => "Sub-account is frozen.",
176            Self::SubAccountPermissionError => "Sub-account permission error.",
177            Self::MasterAccountFrozen => "Master account is frozen.",
178            Self::MasterSubRelationshipExists => "Master-sub relationship already exists.",
179        }
180    }
181}
182
183#[cfg(test)]
184mod tests {
185    use super::*;
186
187    type Sut = GeneralCode;
188
189    #[test]
190    fn test_from_code_i32() {
191        assert_eq!(Sut::from_code(10001), Some(Sut::InvalidParameters));
192        assert_eq!(
193            Sut::from_code(100615),
194            Some(Sut::MasterSubRelationshipExists)
195        );
196        assert_eq!(Sut::from_code(99999), None);
197    }
198
199    #[test]
200    fn test_display() {
201        let error = Sut::InvalidParameters;
202        assert_eq!(error.to_string(), "10001 - Invalid parameter(s).");
203        let error = Sut::MasterSubRelationshipExists;
204        assert_eq!(
205            error.to_string(),
206            "100615 - Master-sub relationship already exists."
207        );
208    }
209}