1use crate::responses::ApiError;
2use std::error::Error as StdErrorTrait;
3
4#[derive(Debug)]
5pub enum Error {
7 InvalidToken,
9
10 TokenConfig(String),
12
13 AccountNotFound,
15
16 PositionNotFound(String, String),
18
19 Request(reqwest::Error),
21
22 BoxedError(Box<dyn StdErrorTrait + Send + Sync>),
23
24 Url(url::ParseError),
26
27 StreamIssue(String),
29
30 StopStream,
32
33 Json(serde_json::Error),
35
36 IoError(std::io::Error),
38
39 SymbolNotSet,
41
42 AccountIdNotSet,
44
45 TradeActionNotSet,
47
48 TimeInForceNotSet,
50
51 OrderTypeNotSet,
53
54 OrderNotFound(String),
56
57 QuantityNotSet,
59
60 OptionLegsNotSet,
62
63 OrderRequestsNotSet,
65
66 OrderGroupTypeNotSet,
68
69 BadRequest(String),
71
72 Unauthorized(String),
74
75 Forbidden(String),
77
78 TooManyRequests(String),
80
81 InternalServerError(String),
83
84 GatewayTimeout(String),
86
87 UnknownTradeStationAPIError(String),
89}
90impl Error {
91 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 {}
105impl std::fmt::Display for Error {
107 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}
158impl From<reqwest::Error> for Error {
160 fn from(err: reqwest::Error) -> Error {
161 Error::Request(err)
162 }
163}
164impl From<Box<dyn StdErrorTrait + Send + Sync>> for Error {
166 fn from(err: Box<dyn StdErrorTrait + Send + Sync>) -> Self {
167 Error::BoxedError(err)
168 }
169}
170impl From<serde_json::Error> for Error {
172 fn from(err: serde_json::Error) -> Error {
173 Error::Json(err)
174 }
175}
176impl 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}