use miette::Diagnostic;
use sioc_socket::packet::{Directive, Ns};
use thiserror::Error;
use tokio::sync::{mpsc, oneshot};
use tokio::task::JoinError;
#[derive(Debug, Error, Diagnostic)]
#[error("payload error for `{type_name}`: {source}")]
#[diagnostic(code(sioc::payload))]
pub struct PayloadError {
type_name: &'static str,
#[source]
source: serde_path_to_error::Error<serde_json::Error>,
}
impl PayloadError {
pub fn new<T>(source: serde_path_to_error::Error<serde_json::Error>) -> Self {
Self {
type_name: std::any::type_name::<T>(),
source,
}
}
}
pub type Result<T, E = Error> = std::result::Result<T, E>;
#[derive(Debug, Error, Diagnostic)]
#[error(transparent)]
#[diagnostic(transparent)]
pub enum Error {
Builder(#[from] ClientBuilderError),
Client(#[from] ClientError),
Socket(#[from] SocketError),
Event(#[from] EventError),
Ack(#[from] AckError),
}
#[derive(Debug, Error, Diagnostic)]
pub enum ClientBuilderError {
#[error("invalid URL")]
#[diagnostic(code(sioc::builder::url))]
Url(#[from] url::ParseError),
}
#[derive(Debug, Error, Diagnostic)]
pub enum ClientError {
#[error(transparent)]
#[diagnostic(transparent)]
Manager(#[from] sioc_socket::error::ManagerError),
#[error("failed to join socket manager task")]
#[diagnostic(code(sioc::client::join))]
Join(#[from] JoinError),
}
#[derive(Debug, Error, Diagnostic)]
pub enum SocketError {
#[error("failed to send directive to socket manager")]
#[diagnostic(code(sioc::socket::send))]
Send(#[from] mpsc::error::SendError<Ns<Directive>>),
#[error("failed to serialize payload")]
#[diagnostic(code(sioc::socket::payload))]
Payload(#[from] PayloadError),
}
#[derive(Debug, Error, Diagnostic)]
pub enum EventError {
#[error("failed to deserialize event payload")]
#[diagnostic(code(sioc::event::payload))]
Payload(#[from] PayloadError),
#[error("invalid ack ID for the event type")]
#[diagnostic(code(sioc::event::ack_id))]
AckId(#[from] AckIdError),
#[error("invalid attachments for the event type")]
#[diagnostic(code(sioc::event::attachments))]
Attachments(#[from] AttachmentsError),
}
#[derive(Debug, Error, Diagnostic)]
pub enum AckError {
#[error("failed to receive ack")]
#[diagnostic(
code(sioc::ack::recv),
help("the ack sender was dropped before responding; the connection may have been lost")
)]
Recv(#[from] oneshot::error::RecvError),
#[error("failed to parse ack payload")]
#[diagnostic(code(sioc::ack::payload))]
Payload(#[from] PayloadError),
#[error("invalid attachments for the ack type")]
#[diagnostic(code(sioc::ack::attachments))]
Attachments(#[from] AttachmentsError),
}
#[derive(Debug, Error, Diagnostic)]
pub enum AckIdError {
#[error("ack ID was missing")]
#[diagnostic(
code(sioc::ack_id::missing),
help(
"event type declares `HasAck` but the server sent no ack ID; verify the server's protocol"
)
)]
Missing,
#[error("ack ID was unexpected")]
#[diagnostic(
code(sioc::ack_id::unexpected),
help(
"event type declares `NoAck` but the server sent an ack ID; consider using `HasAck<A>`"
)
)]
Unexpected,
}
#[derive(Debug, Error, Diagnostic)]
pub enum AttachmentsError {
#[error("attachments were missing")]
#[diagnostic(
code(sioc::attachments::missing),
help(
"type declares `HasBinary` but no attachments were in the packet; verify the server's protocol"
)
)]
Missing,
#[error("attachments were unexpected")]
#[diagnostic(
code(sioc::attachments::unexpected),
help(
"type declares `NoBinary` but the packet contained attachments; consider using `HasBinary`"
)
)]
Unexpected,
}