rustun/
error.rs

1use fibers::sync::oneshot::MonitorError;
2use std::io;
3use std::sync::mpsc::SendError;
4use stun_codec::rfc5389::attributes::ErrorCode;
5use stun_codec::AttributeType;
6use trackable::error::{self, ErrorKindExt, TrackableError};
7
8/// This crate specific `Error` type.
9#[derive(Debug, Clone, TrackableError)]
10pub struct Error(TrackableError<ErrorKind>);
11impl From<MonitorError<Error>> for Error {
12    fn from(f: MonitorError<Error>) -> Self {
13        f.unwrap_or_else(|| {
14            ErrorKind::Other
15                .cause("Monitor channel has disconnected")
16                .into()
17        })
18    }
19}
20impl From<io::Error> for Error {
21    fn from(f: io::Error) -> Self {
22        ErrorKind::Other.cause(f).into()
23    }
24}
25impl<T> From<SendError<T>> for Error {
26    fn from(_: SendError<T>) -> Self {
27        ErrorKind::Other.cause("Receiver has terminated").into()
28    }
29}
30impl From<bytecodec::Error> for Error {
31    fn from(f: bytecodec::Error) -> Self {
32        let original_error_kind = *f.kind();
33        let kind = match original_error_kind {
34            bytecodec::ErrorKind::InvalidInput => ErrorKind::InvalidInput,
35            _ => ErrorKind::Other,
36        };
37        track!(kind.takes_over(f); original_error_kind).into()
38    }
39}
40impl From<MessageError> for Error {
41    fn from(f: MessageError) -> Self {
42        ErrorKind::InvalidMessage(f.kind().clone())
43            .takes_over(f)
44            .into()
45    }
46}
47impl From<ErrorCode> for Error {
48    fn from(f: ErrorCode) -> Self {
49        ErrorKind::Other
50            .cause(format!("STUN error response: {f:?}"))
51            .into()
52    }
53}
54impl From<fibers_transport::Error> for Error {
55    fn from(f: fibers_transport::Error) -> Self {
56        let original_error_kind = *f.kind();
57        let kind = match original_error_kind {
58            fibers_transport::ErrorKind::InvalidInput => ErrorKind::InvalidInput,
59            _ => ErrorKind::Other,
60        };
61        track!(kind.takes_over(f); original_error_kind).into()
62    }
63}
64
65/// Possible error kinds.
66#[derive(Debug, Clone)]
67pub enum ErrorKind {
68    /// Input is invalid.
69    InvalidInput,
70
71    /// A message is invalid.
72    ///
73    /// This error does not affect the overall execution of a channel/client/server.
74    InvalidMessage(MessageErrorKind),
75
76    /// Other errors.
77    Other,
78}
79impl error::ErrorKind for ErrorKind {}
80
81/// Message level error.
82#[derive(Debug, Clone, TrackableError)]
83#[trackable(error_kind = "MessageErrorKind")]
84pub struct MessageError(TrackableError<MessageErrorKind>);
85impl From<MonitorError<MessageError>> for MessageError {
86    fn from(f: MonitorError<MessageError>) -> Self {
87        f.unwrap_or_else(|| {
88            MessageErrorKind::Other
89                .cause("`Channel` instance has dropped")
90                .into()
91        })
92    }
93}
94impl From<Error> for MessageError {
95    fn from(f: Error) -> Self {
96        let original_error_kind = f.kind().clone();
97        track!(MessageErrorKind::Other.takes_over(f); original_error_kind).into()
98    }
99}
100impl From<fibers_transport::Error> for MessageError {
101    fn from(f: fibers_transport::Error) -> Self {
102        let original_error_kind = *f.kind();
103        let kind = match original_error_kind {
104            fibers_transport::ErrorKind::InvalidInput => MessageErrorKind::InvalidInput,
105            _ => MessageErrorKind::Other,
106        };
107        track!(kind.takes_over(f); original_error_kind).into()
108    }
109}
110
111/// Possible error kinds.
112#[derive(Debug, Clone)]
113pub enum MessageErrorKind {
114    /// Unexpected response message.
115    UnexpectedResponse,
116
117    /// There are some malformed attributes in a message.
118    MalformedAttribute,
119
120    /// There are unknown comprehension-required attributes.
121    ///
122    /// If a server receives a message that contains unknown comprehension-required attributes,
123    /// it should reply an `ErrorResponse` message that has the [`UnknownAttribute`] error code and
124    /// an [`UnknownAttributes`] attribute.
125    ///
126    /// [`UnknownAttribute`]: https://docs.rs/stun_codec/0.1/stun_codec/rfc5389/errors/struct.UnknownAttribute.html
127    /// [`UnknownAttributes`]: https://docs.rs/stun_codec/0.1/stun_codec/rfc5389/attributes/struct.UnknownAttributes.html
128    UnknownAttributes(Vec<AttributeType>),
129
130    /// Input is invalid.
131    InvalidInput,
132
133    /// Operation timed out.
134    Timeout,
135
136    /// Other errors.
137    Other,
138}
139impl error::ErrorKind for MessageErrorKind {}