use engineioxide::{sid::Sid, socket::DisconnectReason as EIoDisconnectReason};
use std::fmt::{Debug, Display};
use tokio::{sync::mpsc::error::TrySendError, time::error::Elapsed};
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("error serializing json packet: {0:?}")]
Serialize(#[from] serde_json::Error),
#[error("invalid packet type")]
InvalidPacketType,
#[error("invalid event name")]
InvalidEventName,
#[error("invalid namespace")]
InvalidNamespace,
#[error("cannot find socketio socket")]
SocketGone(Sid),
#[error("adapter error: {0}")]
Adapter(#[from] AdapterError),
}
#[derive(thiserror::Error, Debug)]
pub enum AckError {
#[error("cannot deserialize json packet from ack response: {0:?}")]
Serde(#[from] serde_json::Error),
#[error("ack timeout error")]
Timeout,
#[error("adapter error: {0}")]
Adapter(#[from] AdapterError),
#[error("Error sending data through the engine.io socket: {0:?}")]
Socket(#[from] SocketError),
}
#[derive(Debug, thiserror::Error)]
pub enum BroadcastError {
#[error("Error sending data through the engine.io socket: {0:?}")]
Socket(Vec<SocketError>),
#[error("Error serializing JSON packet: {0:?}")]
Serialize(#[from] serde_json::Error),
#[error("Adapter error: {0}")]
Adapter(#[from] AdapterError),
}
#[derive(thiserror::Error, Debug)]
pub enum SendError {
#[error("Error serializing JSON packet: {0:?}")]
Serialize(#[from] serde_json::Error),
#[error("Error sending data through the engine.io socket: {0:?}")]
Socket(#[from] SocketError),
}
#[derive(thiserror::Error, Debug)]
pub enum SocketError {
#[error("internal channel full error")]
InternalChannelFull,
#[error("socket closed")]
Closed,
}
#[derive(thiserror::Error, Debug)]
pub enum DisconnectError {
#[error("internal channel full error")]
InternalChannelFull,
#[error("adapter error: {0:?}")]
Adapter(#[from] AdapterError),
}
#[derive(Debug, thiserror::Error)]
pub struct AdapterError(#[from] pub Box<dyn std::error::Error + Send>);
impl Display for AdapterError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(&self.0, f)
}
}
impl<T> From<TrySendError<T>> for SocketError {
fn from(value: TrySendError<T>) -> Self {
match value {
TrySendError::Full(_) => Self::InternalChannelFull,
TrySendError::Closed(_) => Self::Closed,
}
}
}
impl From<Vec<SocketError>> for BroadcastError {
fn from(value: Vec<SocketError>) -> Self {
Self::Socket(value)
}
}
impl From<Elapsed> for AckError {
fn from(_: Elapsed) -> Self {
Self::Timeout
}
}
impl From<&Error> for Option<EIoDisconnectReason> {
fn from(value: &Error) -> Self {
use EIoDisconnectReason::*;
match value {
Error::SocketGone(_) => Some(TransportClose),
Error::Serialize(_) | Error::InvalidPacketType | Error::InvalidEventName => {
Some(PacketParsingError)
}
Error::Adapter(_) | Error::InvalidNamespace => None,
}
}
}