1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
use crate::api::Mode;
use chrono::prelude::*;
/// In general, an error will be returned in the following format.
/// Lemons docks: [Error Handling](https://docs.lemon.markets/error-handling)
use reqwest::{Error as ReqwestError, StatusCode};
use serde::{Deserialize, Serialize};
use serde_json::Error as JsonError;
use thiserror::Error;
/// Error type for the library
#[derive(Debug, Error)]
pub enum Error {
#[error("Encountered an Reqwest related error")]
/// Error type for Reqwest errors
Reqwest(
#[from]
#[source]
ReqwestError,
),
/// Error type for Json errors
#[error("Encountered an Json related error")]
Json(#[from] JsonError),
/// Error type for StatusCode errors
#[error("HTTP Error {0}")]
Http(StatusCode),
/// Error type for other errors
#[error("{0}")]
Str(String),
}
/// Error type for the Lemon API
#[derive(Deserialize)]
pub struct LemonError {
/// The time that the error occurred
time: DateTime<Utc>,
/// API mode.
mode: Mode,
/// Status Code of the error
status: String,
/// Lemon API error code
error_code: ErrorCode,
/// Error message
error_message: String,
}
/// Error codes for the Lemon API
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "snake_case")]
pub enum ErrorCode {
/// The API key is not provided in the HTTP header,
/// cannot be decoded by the backend,
/// or the API Key does not exist.
Unauthorized,
/// The API key is revoked or user is deleted/suspended.
TokenInvalid,
/// The API key has exceeded its rate limit.
/// Please respect the value of the Retry-After
/// header before performing another request.
RateLimitExceeded,
// TODO: Add [xxx_not_found]
/// An error occurred in the backend.
/// This is not your fault.
/// We will investigate this.
InternalError,
/// Same idempotency has been used within current 7 day period.
OrderIdempotencyViolation,
/// Cannot withdraw money because the PIN is not provided in the request (money only).
PinMissing,
/// Cannot withdraw money because the PIN is not set (money only)
PinNotSet,
/// Cannot withdraw money because the pin verification failed
PinInvalid,
/// Cannot withdraw money because there are insufficient funds on the account
WithdrawInsufficientFunds,
/// Cannot withdraw money because the daily payout limit is exceeded
WithdrawLimitExceeded,
/// Cannot withdraw money because the maximal daily request limit is exceeded
WithdrawRequestLimitExceeded,
/// Cannot update address_country when trading is enabled or user is onboarded
ForbiddenInCurrentState,
/// Cannot update trading plan to basic/pro
PlanNotAllowed,
/// insufficient instrument holdings [on order sell]
InsufficientHoldings,
/// cannot place order if one expires before market opens again
OrderExpirationDateInvalid,
/// cannot place/activate buy order if estimated total price is greater than 25k Euro
OrderTotalPriceLimitExceeded,
///cannot place order in ALLDAY for MONEY env
ForbiddenForVenue,
/// cannot place order if trading is not enabled
TradingDisabled,
///maximum daily amount of orders reached
OrderLimitExceeded,
///failed to place order if instrument is not tradable
InstrumentNotTradable,
///cannot place/activate buy order because of insufficient account funds
AccountInsufficientFunds,
///cannot place/activate order because trading is blocked globally
TradingBlocked,
///cannot activate order if its status != inactive
OrderNotInactive,
/// cannot delete order if its not in cancelling/cancelled/expired/executed/rejected state
OrderNotTerminated,
}
impl std::fmt::Display for ErrorCode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
impl std::fmt::Display for LemonError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(
f,
"time: {}, mode: {}, status: {}, error_code: {}, error_message: {}",
self.time, self.mode, self.status, self.error_code, self.error_message
)
}
}