use actix_http::ws;
use crossbeam_channel::RecvError;
use std::{error, fmt};
use tokio::io;
#[derive(Debug)]
pub enum ParseError {
MalformedMessage(Box<dyn error::Error + Send + Sync + 'static>),
MalformedReducedToString(String),
}
impl error::Error for ParseError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
ParseError::MalformedMessage(_) => None,
ParseError::MalformedReducedToString(_) => None,
}
}
}
impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ParseError::MalformedMessage(err) => write!(f, "Malformed message {}", err),
ParseError::MalformedReducedToString(msg) => f.write_str(msg),
}
}
}
#[derive(Debug)]
pub enum ReactorError {
WsStartError(String),
ListenError(WebSocketError),
RequestSendError(String),
ReactorShutdownError(String),
ShutdownHandleErrors(Vec<WebSocketError>),
IoError(io::Error),
}
impl error::Error for ReactorError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
ReactorError::ListenError(err) => Some(err),
ReactorError::WsStartError(_) => None,
ReactorError::RequestSendError(_) => None,
ReactorError::ReactorShutdownError(_) => None,
ReactorError::ShutdownHandleErrors(_) => None,
ReactorError::IoError(err) => Some(err),
}
}
}
impl fmt::Display for ReactorError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ReactorError::ListenError(err) => write!(f, "{}", err),
ReactorError::WsStartError(err) => write!(f, "{}", err),
ReactorError::RequestSendError(err) => write!(f, "{}", err),
ReactorError::ReactorShutdownError(err) => write!(f, "{}", err),
ReactorError::ShutdownHandleErrors(err) => {
let err_message = err
.iter()
.map(|err| format!("{}", err))
.collect::<Vec<String>>()
.join(", ");
write!(f, "Websockets did not shut down correctly: {}", err_message)
}
ReactorError::IoError(err) => write!(f, "IO Error: {}", err),
}
}
}
impl From<io::Error> for ReactorError {
fn from(err: io::Error) -> Self {
ReactorError::IoError(err)
}
}
impl From<WebSocketError> for ReactorError {
fn from(err: WebSocketError) -> Self {
ReactorError::ListenError(err)
}
}
#[derive(Debug)]
pub enum WebSocketError {
HyperError(hyper::error::Error),
ProtocolError(ws::ProtocolError),
ShutdownHandleError(RecvError),
RequestBuilderError(String),
AbnormalShutdownError {
protocol_error: ws::ProtocolError,
shutdown_error: ws::ProtocolError,
},
OnFailError {
original_error: Box<dyn error::Error + Send + Sync + 'static>,
on_fail_error: Box<dyn error::Error + Send + Sync + 'static>,
},
NoParserDefinedError,
ParserError {
parse_error: ParseError,
shutdown_error: Option<ws::ProtocolError>,
},
ListenError(String),
ConnectError(String),
ReconnectError(String),
OnFailCallbackError(String),
}
impl error::Error for WebSocketError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
WebSocketError::HyperError(err) => Some(err),
WebSocketError::ProtocolError(_) => None,
WebSocketError::ShutdownHandleError(err) => Some(err),
WebSocketError::RequestBuilderError(_) => None,
WebSocketError::AbnormalShutdownError { .. } => None,
WebSocketError::OnFailError { .. } => None,
WebSocketError::NoParserDefinedError => None,
WebSocketError::ParserError { .. } => None,
WebSocketError::ListenError(_) => None,
WebSocketError::ConnectError(_) => None,
WebSocketError::ReconnectError(_) => None,
WebSocketError::OnFailCallbackError(_) => None,
}
}
}
impl fmt::Display for WebSocketError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
WebSocketError::HyperError(err) => write!(f, "Hyper Error: {}", err),
WebSocketError::ProtocolError(err) => write!(f, "Protocol Error: {}", err),
WebSocketError::ShutdownHandleError(err) => {
write!(f, "Shutdown handle failed unexpectedly: {}", err)
}
WebSocketError::RequestBuilderError(err) => {
write!(f, "Failed to build request: {}", err)
}
WebSocketError::AbnormalShutdownError {
protocol_error,
shutdown_error,
} => write!(
f,
"A shutdown error \
occurred while handling protocol error: protocol error {}, shutdown error {}",
protocol_error, shutdown_error
),
WebSocketError::OnFailError {
on_fail_error,
original_error,
} => write!(
f,
"A failure occured while executing \
the on fail callback: original error: {}, on fail error: {}",
on_fail_error, original_error
),
WebSocketError::NoParserDefinedError => write!(f, "Parsing function required"),
WebSocketError::ParserError {
parse_error,
shutdown_error: Some(shutdown_error),
} => write!(
f,
"Failed to parse message from server: parse error: {} shutdown error: {}",
parse_error, shutdown_error
),
WebSocketError::ParserError {
parse_error,
shutdown_error: None,
} => write!(
f,
"Failed to parse message from server: parse error: {}",
parse_error
),
WebSocketError::ListenError(err) => write!(f, "{}", err),
WebSocketError::ConnectError(err) => write!(f, "{}", err),
WebSocketError::ReconnectError(err) => write!(f, "{}", err),
WebSocketError::OnFailCallbackError(err) => write!(f, "{}", err),
}
}
}
impl From<hyper::error::Error> for WebSocketError {
fn from(err: hyper::error::Error) -> Self {
WebSocketError::HyperError(err)
}
}
impl From<ws::ProtocolError> for WebSocketError {
fn from(err: ws::ProtocolError) -> Self {
WebSocketError::ProtocolError(err)
}
}
impl From<RecvError> for WebSocketError {
fn from(err: RecvError) -> Self {
WebSocketError::ShutdownHandleError(err)
}
}