tradestation/
error.rs

1use crate::responses::ApiError;
2use std::error::Error as StdErrorTrait;
3
4#[derive(Debug)]
5/// TradeStation API Client Error
6pub enum Error {
7    /// Issue with your current `Token` the `Client` is using.
8    InvalidToken,
9
10    /// Issue building a `Token`.
11    TokenConfig(String),
12
13    /// An `Account` was not found for a given account id.
14    AccountNotFound,
15
16    /// A `Position` was not found for a given position id.
17    PositionNotFound(String, String),
18
19    /// An HTTP request error.
20    Request(reqwest::Error),
21
22    BoxedError(Box<dyn StdErrorTrait + Send + Sync>),
23
24    /// An error during URL parsing.
25    Url(url::ParseError),
26
27    /// Error while in stream
28    StreamIssue(String),
29
30    /// Use this to stop a stream connection.
31    StopStream,
32
33    /// Error with JSON serializing or deseializing.
34    Json(serde_json::Error),
35
36    /// Issue reading a stream
37    IoError(std::io::Error),
38
39    /// No symbol set when one was required.
40    SymbolNotSet,
41
42    /// Account Id not set when one was required.
43    AccountIdNotSet,
44
45    /// Trade Action not set when one was required.
46    TradeActionNotSet,
47
48    /// Time In Force not set when one was required.
49    TimeInForceNotSet,
50
51    /// Order Type not set when one was required.
52    OrderTypeNotSet,
53
54    /// An [`crate::orders::Order`] was not found for a give order id.
55    OrderNotFound(String),
56
57    /// Quantity not set when one was required.
58    QuantityNotSet,
59
60    /// No Option legs set when they were required.
61    OptionLegsNotSet,
62
63    /// Order Requests not set when they're required.
64    OrderRequestsNotSet,
65
66    /// Order Group Type not set when it's required.
67    OrderGroupTypeNotSet,
68
69    /// TradeStation API Error for a bad request
70    BadRequest(String),
71
72    /// TradeStation API Error for an unauthorized request.
73    Unauthorized(String),
74
75    /// TradeStation API Error for a forbidden request.
76    Forbidden(String),
77
78    /// TradeStation API Error for too many requests.
79    TooManyRequests(String),
80
81    /// TradeStation API Error for an internal server error.
82    InternalServerError(String),
83
84    /// TradeStation API Error for a gateway timeout.
85    GatewayTimeout(String),
86
87    /// TradeStation API Error for an unkown error.
88    UnknownTradeStationAPIError(String),
89}
90impl Error {
91    /// Convert a error from the tradestation api to `Some(Error)` or `None` if not supported.
92    pub fn from_api_error(api_err: ApiError) -> Error {
93        match api_err.error.as_str() {
94            "BadRequest" => Error::BadRequest(api_err.message),
95            "Unauthorized" => Error::Unauthorized(api_err.message),
96            "Forbidden" => Error::Forbidden(api_err.message),
97            "TooManyRequests" => Error::TooManyRequests(api_err.message),
98            "InternalServerError" => Error::InternalServerError(api_err.message),
99            "GatewayTimeout" => Error::GatewayTimeout(api_err.message),
100            _ => Error::UnknownTradeStationAPIError(api_err.message),
101        }
102    }
103}
104impl StdErrorTrait for Error {}
105/// Implement display trait for `Error`
106impl std::fmt::Display for Error {
107    /// The error message display format
108    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
109        match self {
110            Self::InvalidToken => write!(f, "Invalid `Token` may be expired, bad, or `None`"),
111            Self::TokenConfig(e) => write!(f, "Error building `Token`: {e}"),
112            Self::AccountNotFound => {
113                write!(f, "Couldn't find an account registered to you with that id")
114            }
115            Self::PositionNotFound(position_id, account_id) => {
116                write!(
117                    f,
118                    "Couldn't find a position with id: {position_id} in account with id: {account_id}",
119                )
120            }
121            Self::OrderNotFound(order_id) => {
122                write!(f, "Failed to find an order for: #{order_id}")
123            }
124            Self::Request(e) => write!(f, "{e:?}"),
125            Self::Url(e) => write!(f, "{e:?}"),
126            Self::BoxedError(e) => write!(f, "{e:?}"),
127            Self::StreamIssue(e) => write!(f, "Issue during stream: {e}"),
128            Self::StopStream => write!(f, "WARNING: You've stopped a stream!"),
129            Self::Json(e) => write!(f, "JSON Error: {e:?}"),
130            Self::IoError(e) => write!(f, "Issue reading stream: {e}"),
131            Self::SymbolNotSet => write!(f, "ERROR: You need to set the symbol."),
132            Self::OptionLegsNotSet => write!(f, "ERROR: You need to set the option legs."),
133            Self::BadRequest(msg) => write!(f, "TradeStation API ERROR: {msg}"),
134            Self::Unauthorized(msg) => write!(f, "TradeStation API ERROR: {msg}"),
135            Self::Forbidden(msg) => write!(f, "TradeStation API ERROR: {msg}"),
136            Self::TooManyRequests(msg) => write!(f, "TradeStation API ERROR: {msg}"),
137            Self::InternalServerError(msg) => write!(f, "TradeStation API ERROR: {msg}"),
138            Self::GatewayTimeout(msg) => write!(f, "TradeStation API ERROR: {msg}"),
139            Self::UnknownTradeStationAPIError(msg) => {
140                write!(f, "Unknown TradeStation API ERROR: {msg}.\n Sumbit an issue, so this can be handled: https://github.com/antonio-hickey/tradestation-rs")
141            }
142            Self::AccountIdNotSet => write!(f, "ERROR: account_id not set when it's required."),
143            Self::TradeActionNotSet => write!(f, "ERROR: trade_action not set when it's required."),
144            Self::OrderTypeNotSet => write!(f, "ERROR: order_type not set when it's required."),
145            Self::TimeInForceNotSet => {
146                write!(f, "ERROR: time_in_force not set when it's required.")
147            }
148            Self::QuantityNotSet => write!(f, "ERROR: quantity not set when it's required."),
149            Self::OrderRequestsNotSet => {
150                write!(f, "ERROR: order requests not set when they're required.")
151            }
152            Self::OrderGroupTypeNotSet => {
153                write!(f, "ERROR: order group type not set when it's required.")
154            }
155        }
156    }
157}
158/// Implement error conversion (`reqwest::Error` -> `Error`)
159impl From<reqwest::Error> for Error {
160    fn from(err: reqwest::Error) -> Error {
161        Error::Request(err)
162    }
163}
164/// Implement error conversion (`<Box<dyn StdErrorTrait + Send + Sync>>` -> `Error`)
165impl From<Box<dyn StdErrorTrait + Send + Sync>> for Error {
166    fn from(err: Box<dyn StdErrorTrait + Send + Sync>) -> Self {
167        Error::BoxedError(err)
168    }
169}
170/// Implement error conversion (`serde_json::Error` -> `Error`)
171impl From<serde_json::Error> for Error {
172    fn from(err: serde_json::Error) -> Error {
173        Error::Json(err)
174    }
175}
176/// Implement error conversion (`std::io::Error` -> `Error`)
177impl From<std::io::Error> for Error {
178    fn from(err: std::io::Error) -> Self {
179        Error::IoError(err)
180    }
181}
182impl From<url::ParseError> for Error {
183    fn from(err: url::ParseError) -> Self {
184        Error::Url(err)
185    }
186}