1use crate::model::track::TrackError;
2
3use std::error::Error;
4use std::fmt::{Display, Formatter, Result};
5use std::io::Error as IoError;
6
7use ::http::header::InvalidHeaderValue;
8use ::http::method::InvalidMethod;
9use ::http::uri::InvalidUri;
10use ::http::Error as HttpError;
11use hyper::Error as HyperError;
12use hyper_util::client::legacy::Error as HyperClientError;
13use oneshot::RecvError;
14use tokio::sync::mpsc::error::SendError;
15#[cfg(feature = "_tungstenite")]
16use tokio_tungstenite::tungstenite::error::Error as TungsteniteError;
17#[cfg(feature = "_websockets")]
18use tokio_websockets::error::Error as WebsocketsError;
19
20#[cfg(feature = "python")]
21use pyo3::exceptions::PyException;
22#[cfg(feature = "python")]
23use pyo3::PyErr;
24
25pub type LavalinkResult<T> = std::result::Result<T, LavalinkError>;
26
27#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
28pub struct ResponseError {
30 pub status: u16,
31 pub timestamp: u64,
32 pub error: String,
33 pub message: String,
34 pub path: String,
35 pub trace: Option<String>,
36}
37
38#[derive(Serialize, Deserialize)]
39#[serde(untagged)]
40pub(crate) enum RequestResult<T> {
41 Ok(T),
42 Err(ResponseError),
43}
44
45impl<T> RequestResult<T> {
46 pub fn to_result(self) -> std::result::Result<T, ResponseError> {
47 match self {
48 Self::Ok(x) => Ok(x),
49 Self::Err(x) => Err(x),
50 }
51 }
52}
53
54#[derive(Debug)]
55#[non_exhaustive]
56pub enum LavalinkError {
58 IoError(IoError),
59 #[cfg(feature = "_tungstenite")]
60 WebsocketError(TungsteniteError),
61 #[cfg(feature = "_websockets")]
62 WebsocketError(WebsocketsError),
63 InvalidHeaderValue(InvalidHeaderValue),
64 HyperError(HyperError),
65 HyperClientError(HyperClientError),
66 HttpError(HttpError),
67 InvalidUri(InvalidUri),
68 InvalidMethod(InvalidMethod),
69 ChannelSendError,
70 ChannelReceiveError(RecvError),
71 SerdeErrorQs(serde_qs::Error),
72 SerdeErrorJson(serde_json::Error),
73
74 ResponseError(ResponseError),
75 NoSessionPresent,
76 TrackError(TrackError),
77 InvalidDataType,
78 Timeout,
79}
80
81impl Error for LavalinkError {}
82
83impl Display for LavalinkError {
84 fn fmt(&self, f: &mut Formatter) -> Result {
85 match self {
86 LavalinkError::WebsocketError(why) => {
87 write!(
88 f,
89 "Error while sending payload to the websocket => {:?}",
90 why
91 )
92 }
93 LavalinkError::IoError(why) => {
94 write!(f, "I/O Error => {:?}", why)
95 }
96 LavalinkError::InvalidHeaderValue(why) => {
97 write!(f, "Invalid Header Value => {:?}", why)
98 }
99 LavalinkError::HttpError(why) => {
100 write!(f, "HttpError => {:?}", why)
101 }
102 LavalinkError::InvalidUri(why) => {
103 write!(f, "Invalid URI => {:?}", why)
104 }
105 LavalinkError::InvalidMethod(why) => {
106 write!(f, "Invalid HTTP request method => {:?}", why)
107 }
108 LavalinkError::HyperError(why) => {
109 write!(f, "Hyper Error => {:?}", why)
110 }
111 LavalinkError::HyperClientError(why) => {
112 write!(f, "Hyper Client Error => {:?}", why)
113 }
114 LavalinkError::ChannelSendError => {
115 write!(f, "The channel receiver is closed.")
116 }
117 LavalinkError::ChannelReceiveError(why) => {
118 write!(f, "Error receiving from player context: {:?}", why)
119 }
120 LavalinkError::SerdeErrorQs(why) => {
121 write!(f, "Error serializing or desesrializing qs => {:?}", why)
122 }
123 LavalinkError::SerdeErrorJson(why) => {
124 write!(f, "Error serializing or desesrializing json => {:?}", why)
125 }
126
127 LavalinkError::NoSessionPresent => {
128 write!(
129 f,
130 "Please, call client.create_session() for this method to work correctly."
131 )
132 }
133 LavalinkError::ResponseError(why) => {
134 write!(f, "Error from lavalink server: {:?}", why)
135 }
136 LavalinkError::TrackError(why) => {
137 write!(f, "Error loading tracks: {:?}", why)
138 }
139 LavalinkError::InvalidDataType => {
140 write!(f, "The value type provided does not match the data type id, or no data was ever provided.")
141 }
142 LavalinkError::Timeout => {
143 write!(f, "Timeout reached while waiting for response.")
144 }
145 }
146 }
147}
148
149impl From<IoError> for LavalinkError {
150 fn from(err: IoError) -> LavalinkError {
151 LavalinkError::IoError(err)
152 }
153}
154
155impl From<ResponseError> for LavalinkError {
156 fn from(err: ResponseError) -> LavalinkError {
157 LavalinkError::ResponseError(err)
158 }
159}
160
161impl From<TrackError> for LavalinkError {
162 fn from(err: TrackError) -> LavalinkError {
163 LavalinkError::TrackError(err)
164 }
165}
166
167#[cfg(feature = "_tungstenite")]
168impl From<TungsteniteError> for LavalinkError {
169 fn from(err: TungsteniteError) -> LavalinkError {
170 LavalinkError::WebsocketError(err)
171 }
172}
173
174#[cfg(feature = "_websockets")]
175impl From<WebsocketsError> for LavalinkError {
176 fn from(err: WebsocketsError) -> LavalinkError {
177 LavalinkError::WebsocketError(err)
178 }
179}
180
181impl From<InvalidHeaderValue> for LavalinkError {
182 fn from(err: InvalidHeaderValue) -> LavalinkError {
183 LavalinkError::InvalidHeaderValue(err)
184 }
185}
186
187impl From<HttpError> for LavalinkError {
188 fn from(err: HttpError) -> LavalinkError {
189 LavalinkError::HttpError(err)
190 }
191}
192
193impl From<InvalidUri> for LavalinkError {
194 fn from(err: InvalidUri) -> LavalinkError {
195 LavalinkError::InvalidUri(err)
196 }
197}
198
199impl From<InvalidMethod> for LavalinkError {
200 fn from(err: InvalidMethod) -> LavalinkError {
201 LavalinkError::InvalidMethod(err)
202 }
203}
204
205impl From<HyperError> for LavalinkError {
206 fn from(err: HyperError) -> LavalinkError {
207 LavalinkError::HyperError(err)
208 }
209}
210
211impl From<HyperClientError> for LavalinkError {
212 fn from(err: HyperClientError) -> LavalinkError {
213 LavalinkError::HyperClientError(err)
214 }
215}
216
217impl<T> From<SendError<T>> for LavalinkError {
218 fn from(_: SendError<T>) -> LavalinkError {
219 LavalinkError::ChannelSendError
220 }
221}
222
223impl From<RecvError> for LavalinkError {
224 fn from(err: RecvError) -> LavalinkError {
225 LavalinkError::ChannelReceiveError(err)
226 }
227}
228
229impl From<serde_qs::Error> for LavalinkError {
230 fn from(err: serde_qs::Error) -> Self {
231 LavalinkError::SerdeErrorQs(err)
232 }
233}
234
235impl From<serde_json::Error> for LavalinkError {
236 fn from(err: serde_json::Error) -> Self {
237 LavalinkError::SerdeErrorJson(err)
238 }
239}
240
241#[cfg(feature = "python")]
242impl From<LavalinkError> for PyErr {
243 fn from(err: LavalinkError) -> PyErr {
244 error!("{}", err);
245 PyErr::new::<PyException, _>(format!("{:?}", err))
246 }
247}