use fibers::sync::oneshot::MonitorError;
use std::io;
use std::sync::mpsc::SendError;
use stun_codec::rfc5389::attributes::ErrorCode;
use stun_codec::AttributeType;
use trackable::error::{self, ErrorKindExt, TrackableError};
#[derive(Debug, Clone, TrackableError)]
pub struct Error(TrackableError<ErrorKind>);
impl From<MonitorError<Error>> for Error {
fn from(f: MonitorError<Error>) -> Self {
f.unwrap_or_else(|| {
ErrorKind::Other
.cause("Monitor channel has disconnected")
.into()
})
}
}
impl From<io::Error> for Error {
fn from(f: io::Error) -> Self {
ErrorKind::Other.cause(f).into()
}
}
impl<T> From<SendError<T>> for Error {
fn from(_: SendError<T>) -> Self {
ErrorKind::Other.cause("Receiver has terminated").into()
}
}
impl From<bytecodec::Error> for Error {
fn from(f: bytecodec::Error) -> Self {
let original_error_kind = *f.kind();
let kind = match original_error_kind {
bytecodec::ErrorKind::InvalidInput => ErrorKind::InvalidInput,
_ => ErrorKind::Other,
};
track!(kind.takes_over(f); original_error_kind).into()
}
}
impl From<MessageError> for Error {
fn from(f: MessageError) -> Self {
ErrorKind::InvalidMessage(f.kind().clone())
.takes_over(f)
.into()
}
}
impl From<ErrorCode> for Error {
fn from(f: ErrorCode) -> Self {
ErrorKind::Other
.cause(format!("STUN error response: {f:?}"))
.into()
}
}
impl From<fibers_transport::Error> for Error {
fn from(f: fibers_transport::Error) -> Self {
let original_error_kind = *f.kind();
let kind = match original_error_kind {
fibers_transport::ErrorKind::InvalidInput => ErrorKind::InvalidInput,
_ => ErrorKind::Other,
};
track!(kind.takes_over(f); original_error_kind).into()
}
}
#[derive(Debug, Clone)]
pub enum ErrorKind {
InvalidInput,
InvalidMessage(MessageErrorKind),
Other,
}
impl error::ErrorKind for ErrorKind {}
#[derive(Debug, Clone, TrackableError)]
#[trackable(error_kind = "MessageErrorKind")]
pub struct MessageError(TrackableError<MessageErrorKind>);
impl From<MonitorError<MessageError>> for MessageError {
fn from(f: MonitorError<MessageError>) -> Self {
f.unwrap_or_else(|| {
MessageErrorKind::Other
.cause("`Channel` instance has dropped")
.into()
})
}
}
impl From<Error> for MessageError {
fn from(f: Error) -> Self {
let original_error_kind = f.kind().clone();
track!(MessageErrorKind::Other.takes_over(f); original_error_kind).into()
}
}
impl From<fibers_transport::Error> for MessageError {
fn from(f: fibers_transport::Error) -> Self {
let original_error_kind = *f.kind();
let kind = match original_error_kind {
fibers_transport::ErrorKind::InvalidInput => MessageErrorKind::InvalidInput,
_ => MessageErrorKind::Other,
};
track!(kind.takes_over(f); original_error_kind).into()
}
}
#[derive(Debug, Clone)]
pub enum MessageErrorKind {
UnexpectedResponse,
MalformedAttribute,
UnknownAttributes(Vec<AttributeType>),
InvalidInput,
Timeout,
Other,
}
impl error::ErrorKind for MessageErrorKind {}