1use std::collections::TryReserveError;
19use std::convert::{From, Into};
20use std::convert::{Infallible, TryFrom};
21use std::fmt::{Debug, Display, Formatter};
22use std::{error, fmt, io, string};
23
24use crate::thrift::protocol::{
25 TFieldIdentifier, TInputProtocol, TOutputProtocol, TStructIdentifier, TType,
26};
27
28pub enum Error {
58 Transport(TransportError),
62 Protocol(ProtocolError),
66 Application(ApplicationError),
75}
76
77impl Error {
78 pub fn read_application_error_from_in_protocol<T: TInputProtocol>(
82 i: &mut T,
83 ) -> crate::thrift::Result<ApplicationError> {
84 let mut message = "general remote error".to_owned();
85 let mut kind = ApplicationErrorKind::Unknown;
86
87 i.read_struct_begin()?;
88
89 loop {
90 let field_ident = i.read_field_begin()?;
91
92 if field_ident.field_type == TType::Stop {
93 break;
94 }
95
96 let id = field_ident
97 .id
98 .expect("sender should always specify id for non-STOP field");
99
100 match id {
101 1 => {
102 let remote_message = i.read_string()?;
103 i.read_field_end()?;
104 message = remote_message;
105 }
106 2 => {
107 let remote_type_as_int = i.read_i32()?;
108 let remote_kind: ApplicationErrorKind = TryFrom::try_from(remote_type_as_int)
109 .unwrap_or(ApplicationErrorKind::Unknown);
110 i.read_field_end()?;
111 kind = remote_kind;
112 }
113 _ => {
114 i.skip(field_ident.field_type)?;
115 }
116 }
117 }
118
119 i.read_struct_end()?;
120
121 Ok(ApplicationError { kind, message })
122 }
123
124 pub fn write_application_error_to_out_protocol(
129 e: &ApplicationError,
130 o: &mut dyn TOutputProtocol,
131 ) -> crate::thrift::Result<()> {
132 o.write_struct_begin(&TStructIdentifier {
133 name: "TApplicationException".to_owned(),
134 })?;
135
136 let message_field = TFieldIdentifier::new("message", TType::String, 1);
137 let type_field = TFieldIdentifier::new("type", TType::I32, 2);
138
139 o.write_field_begin(&message_field)?;
140 o.write_string(&e.message)?;
141 o.write_field_end()?;
142
143 o.write_field_begin(&type_field)?;
144 o.write_i32(e.kind as i32)?;
145 o.write_field_end()?;
146
147 o.write_field_stop()?;
148 o.write_struct_end()?;
149
150 o.flush()
151 }
152}
153
154impl error::Error for Error {}
155
156impl Debug for Error {
157 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
158 match *self {
159 Error::Transport(ref e) => Debug::fmt(e, f),
160 Error::Protocol(ref e) => Debug::fmt(e, f),
161 Error::Application(ref e) => Debug::fmt(e, f),
162 }
163 }
164}
165
166impl Display for Error {
167 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
168 match *self {
169 Error::Transport(ref e) => Display::fmt(e, f),
170 Error::Protocol(ref e) => Display::fmt(e, f),
171 Error::Application(ref e) => Display::fmt(e, f),
172 }
173 }
174}
175
176impl From<String> for Error {
177 fn from(s: String) -> Self {
178 Error::Application(ApplicationError {
179 kind: ApplicationErrorKind::Unknown,
180 message: s,
181 })
182 }
183}
184
185impl<'a> From<&'a str> for Error {
186 fn from(s: &'a str) -> Self {
187 Error::Application(ApplicationError {
188 kind: ApplicationErrorKind::Unknown,
189 message: String::from(s),
190 })
191 }
192}
193
194impl From<TransportError> for Error {
195 fn from(e: TransportError) -> Self {
196 Error::Transport(e)
197 }
198}
199
200impl From<ProtocolError> for Error {
201 fn from(e: ProtocolError) -> Self {
202 Error::Protocol(e)
203 }
204}
205
206impl From<ApplicationError> for Error {
207 fn from(e: ApplicationError) -> Self {
208 Error::Application(e)
209 }
210}
211
212pub fn new_transport_error<S: Into<String>>(kind: TransportErrorKind, message: S) -> Error {
215 Error::Transport(TransportError::new(kind, message))
216}
217
218#[derive(Debug, Eq, PartialEq)]
220pub struct TransportError {
221 pub kind: TransportErrorKind,
226 pub message: String,
228}
229
230impl TransportError {
231 pub fn new<S: Into<String>>(kind: TransportErrorKind, message: S) -> TransportError {
233 TransportError {
234 kind,
235 message: message.into(),
236 }
237 }
238}
239
240#[non_exhaustive]
244#[derive(Clone, Copy, Eq, Debug, PartialEq)]
245pub enum TransportErrorKind {
246 Unknown = 0,
248 NotOpen = 1,
250 AlreadyOpen = 2,
252 TimedOut = 3,
254 EndOfFile = 4,
256 NegativeSize = 5,
258 SizeLimit = 6,
260}
261
262impl Display for TransportError {
263 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
264 let error_text = match self.kind {
265 TransportErrorKind::Unknown => "transport error",
266 TransportErrorKind::NotOpen => "not open",
267 TransportErrorKind::AlreadyOpen => "already open",
268 TransportErrorKind::TimedOut => "timed out",
269 TransportErrorKind::EndOfFile => "end of file",
270 TransportErrorKind::NegativeSize => "negative size message",
271 TransportErrorKind::SizeLimit => "message too long",
272 };
273
274 write!(f, "{}", error_text)
275 }
276}
277
278impl TryFrom<i32> for TransportErrorKind {
279 type Error = Error;
280 fn try_from(from: i32) -> Result<Self, Self::Error> {
281 match from {
282 0 => Ok(TransportErrorKind::Unknown),
283 1 => Ok(TransportErrorKind::NotOpen),
284 2 => Ok(TransportErrorKind::AlreadyOpen),
285 3 => Ok(TransportErrorKind::TimedOut),
286 4 => Ok(TransportErrorKind::EndOfFile),
287 5 => Ok(TransportErrorKind::NegativeSize),
288 6 => Ok(TransportErrorKind::SizeLimit),
289 _ => Err(Error::Protocol(ProtocolError {
290 kind: ProtocolErrorKind::Unknown,
291 message: format!("cannot convert {} to TransportErrorKind", from),
292 })),
293 }
294 }
295}
296
297impl From<io::Error> for Error {
298 fn from(err: io::Error) -> Self {
299 match err.kind() {
300 io::ErrorKind::ConnectionReset
301 | io::ErrorKind::ConnectionRefused
302 | io::ErrorKind::NotConnected => Error::Transport(TransportError {
303 kind: TransportErrorKind::NotOpen,
304 message: err.to_string(),
305 }),
306 io::ErrorKind::AlreadyExists => Error::Transport(TransportError {
307 kind: TransportErrorKind::AlreadyOpen,
308 message: err.to_string(),
309 }),
310 io::ErrorKind::TimedOut => Error::Transport(TransportError {
311 kind: TransportErrorKind::TimedOut,
312 message: err.to_string(),
313 }),
314 io::ErrorKind::UnexpectedEof => Error::Transport(TransportError {
315 kind: TransportErrorKind::EndOfFile,
316 message: err.to_string(),
317 }),
318 _ => {
319 Error::Transport(TransportError {
320 kind: TransportErrorKind::Unknown,
321 message: err.to_string(), })
323 }
324 }
325 }
326}
327
328impl From<string::FromUtf8Error> for Error {
329 fn from(err: string::FromUtf8Error) -> Self {
330 Error::Protocol(ProtocolError {
331 kind: ProtocolErrorKind::InvalidData,
332 message: err.to_string(), })
334 }
335}
336
337impl From<std::num::TryFromIntError> for Error {
338 fn from(err: std::num::TryFromIntError) -> Self {
339 Error::Protocol(ProtocolError {
340 kind: ProtocolErrorKind::InvalidData,
341 message: err.to_string(),
342 })
343 }
344}
345
346impl From<TryReserveError> for Error {
347 fn from(err: TryReserveError) -> Self {
348 Error::Protocol(ProtocolError {
349 kind: ProtocolErrorKind::SizeLimit,
350 message: err.to_string(),
351 })
352 }
353}
354
355impl From<Infallible> for Error {
356 fn from(err: Infallible) -> Self {
357 Error::Protocol(ProtocolError {
358 kind: ProtocolErrorKind::InvalidData,
359 message: err.to_string(),
360 })
361 }
362}
363
364pub fn new_protocol_error<S: Into<String>>(kind: ProtocolErrorKind, message: S) -> Error {
367 Error::Protocol(ProtocolError::new(kind, message))
368}
369
370#[derive(Debug, Eq, PartialEq)]
372pub struct ProtocolError {
373 pub kind: ProtocolErrorKind,
378 pub message: String,
380}
381
382impl ProtocolError {
383 pub fn new<S: Into<String>>(kind: ProtocolErrorKind, message: S) -> ProtocolError {
385 ProtocolError {
386 kind,
387 message: message.into(),
388 }
389 }
390}
391
392#[non_exhaustive]
396#[derive(Clone, Copy, Eq, Debug, PartialEq)]
397pub enum ProtocolErrorKind {
398 Unknown = 0,
400 InvalidData = 1,
403 NegativeSize = 2,
405 SizeLimit = 3,
407 BadVersion = 4,
409 NotImplemented = 5,
411 DepthLimit = 6,
414}
415
416impl Display for ProtocolError {
417 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
418 let error_text = match self.kind {
419 ProtocolErrorKind::Unknown => "protocol error",
420 ProtocolErrorKind::InvalidData => "bad data",
421 ProtocolErrorKind::NegativeSize => "negative message size",
422 ProtocolErrorKind::SizeLimit => "message too long",
423 ProtocolErrorKind::BadVersion => "invalid thrift version",
424 ProtocolErrorKind::NotImplemented => "not implemented",
425 ProtocolErrorKind::DepthLimit => "maximum skip depth reached",
426 };
427
428 write!(f, "{}", error_text)
429 }
430}
431
432impl TryFrom<i32> for ProtocolErrorKind {
433 type Error = Error;
434 fn try_from(from: i32) -> Result<Self, Self::Error> {
435 match from {
436 0 => Ok(ProtocolErrorKind::Unknown),
437 1 => Ok(ProtocolErrorKind::InvalidData),
438 2 => Ok(ProtocolErrorKind::NegativeSize),
439 3 => Ok(ProtocolErrorKind::SizeLimit),
440 4 => Ok(ProtocolErrorKind::BadVersion),
441 5 => Ok(ProtocolErrorKind::NotImplemented),
442 6 => Ok(ProtocolErrorKind::DepthLimit),
443 _ => Err(Error::Protocol(ProtocolError {
444 kind: ProtocolErrorKind::Unknown,
445 message: format!("cannot convert {} to ProtocolErrorKind", from),
446 })),
447 }
448 }
449}
450
451pub fn new_application_error<S: Into<String>>(kind: ApplicationErrorKind, message: S) -> Error {
454 Error::Application(ApplicationError::new(kind, message))
455}
456
457#[derive(Debug, Eq, PartialEq)]
460pub struct ApplicationError {
461 pub kind: ApplicationErrorKind,
466 pub message: String,
468}
469
470impl ApplicationError {
471 pub fn new<S: Into<String>>(kind: ApplicationErrorKind, message: S) -> ApplicationError {
473 ApplicationError {
474 kind,
475 message: message.into(),
476 }
477 }
478}
479
480#[non_exhaustive]
484#[derive(Clone, Copy, Debug, Eq, PartialEq)]
485pub enum ApplicationErrorKind {
486 Unknown = 0,
488 UnknownMethod = 1,
490 InvalidMessageType = 2,
493 WrongMethodName = 3,
496 BadSequenceId = 4,
498 MissingResult = 5,
500 InternalError = 6,
502 ProtocolError = 7,
505 InvalidTransform = 8, InvalidProtocol = 9, UnsupportedClientType = 10, }
512
513impl Display for ApplicationError {
514 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
515 let error_text = match self.kind {
516 ApplicationErrorKind::Unknown => "service error",
517 ApplicationErrorKind::UnknownMethod => "unknown service method",
518 ApplicationErrorKind::InvalidMessageType => "wrong message type received",
519 ApplicationErrorKind::WrongMethodName => "unknown method reply received",
520 ApplicationErrorKind::BadSequenceId => "out of order sequence id",
521 ApplicationErrorKind::MissingResult => "missing method result",
522 ApplicationErrorKind::InternalError => "remote service threw exception",
523 ApplicationErrorKind::ProtocolError => "protocol error",
524 ApplicationErrorKind::InvalidTransform => "invalid transform",
525 ApplicationErrorKind::InvalidProtocol => "invalid protocol requested",
526 ApplicationErrorKind::UnsupportedClientType => "unsupported protocol client",
527 };
528
529 write!(f, "{}", error_text)
530 }
531}
532
533impl TryFrom<i32> for ApplicationErrorKind {
534 type Error = Error;
535 fn try_from(from: i32) -> Result<Self, Self::Error> {
536 match from {
537 0 => Ok(ApplicationErrorKind::Unknown),
538 1 => Ok(ApplicationErrorKind::UnknownMethod),
539 2 => Ok(ApplicationErrorKind::InvalidMessageType),
540 3 => Ok(ApplicationErrorKind::WrongMethodName),
541 4 => Ok(ApplicationErrorKind::BadSequenceId),
542 5 => Ok(ApplicationErrorKind::MissingResult),
543 6 => Ok(ApplicationErrorKind::InternalError),
544 7 => Ok(ApplicationErrorKind::ProtocolError),
545 8 => Ok(ApplicationErrorKind::InvalidTransform),
546 9 => Ok(ApplicationErrorKind::InvalidProtocol),
547 10 => Ok(ApplicationErrorKind::UnsupportedClientType),
548 _ => Err(Error::Application(ApplicationError {
549 kind: ApplicationErrorKind::Unknown,
550 message: format!("cannot convert {} to ApplicationErrorKind", from),
551 })),
552 }
553 }
554}