use super::error::{self, Error};
#[derive(Debug)]
pub enum Sender {
Downstream(async_channel::Sender<Status<'static>>),
DownstreamListener(async_channel::Sender<Status<'static>>),
Upstream(async_channel::Sender<Status<'static>>),
TemplateReceiver(async_channel::Sender<Status<'static>>),
}
impl Sender {
pub async fn send(
&self,
status: Status<'static>,
) -> Result<(), async_channel::SendError<Status<'_>>> {
match self {
Self::Downstream(inner) => inner.send(status).await,
Self::DownstreamListener(inner) => inner.send(status).await,
Self::Upstream(inner) => inner.send(status).await,
Self::TemplateReceiver(inner) => inner.send(status).await,
}
}
}
impl Clone for Sender {
fn clone(&self) -> Self {
match self {
Self::Downstream(inner) => Self::Downstream(inner.clone()),
Self::DownstreamListener(inner) => Self::DownstreamListener(inner.clone()),
Self::Upstream(inner) => Self::Upstream(inner.clone()),
Self::TemplateReceiver(inner) => Self::TemplateReceiver(inner.clone()),
}
}
}
#[derive(Debug)]
pub enum State<'a> {
DownstreamShutdown(Error<'a>),
UpstreamShutdown(Error<'a>),
UpstreamRogue,
Healthy(String),
}
#[derive(Debug)]
pub struct Status<'a> {
pub state: State<'a>,
}
async fn send_status(
sender: &Sender,
e: error::Error<'static>,
outcome: error_handling::ErrorBranch,
) -> error_handling::ErrorBranch {
match sender {
Sender::Downstream(tx) => {
tx.send(Status {
state: State::Healthy(e.to_string()),
})
.await
.unwrap_or(());
}
Sender::DownstreamListener(tx) => {
tx.send(Status {
state: State::DownstreamShutdown(e),
})
.await
.unwrap_or(());
}
Sender::Upstream(tx) => {
tx.send(Status {
state: State::UpstreamShutdown(e),
})
.await
.unwrap_or(());
}
Sender::TemplateReceiver(tx) => {
tx.send(Status {
state: State::UpstreamShutdown(e),
})
.await
.unwrap_or(());
}
}
outcome
}
pub async fn handle_error(
sender: &Sender,
e: error::Error<'static>,
) -> error_handling::ErrorBranch {
tracing::error!("Error: {:?}", &e);
match e {
Error::VecToSlice32(_) => send_status(sender, e, error_handling::ErrorBranch::Break).await,
Error::BadCliArgs => send_status(sender, e, error_handling::ErrorBranch::Break).await,
Error::BadTomlDeserialize(_) => {
send_status(sender, e, error_handling::ErrorBranch::Break).await
}
Error::BinarySv2(_) => send_status(sender, e, error_handling::ErrorBranch::Break).await,
Error::CodecNoise(_) => send_status(sender, e, error_handling::ErrorBranch::Break).await,
Error::FramingSv2(_) => send_status(sender, e, error_handling::ErrorBranch::Break).await,
Error::Io(_) => send_status(sender, e, error_handling::ErrorBranch::Break).await,
Error::ParseInt(_) => send_status(sender, e, error_handling::ErrorBranch::Break).await,
Error::RolesSv2Logic(_) => send_status(sender, e, error_handling::ErrorBranch::Break).await,
Error::UpstreamIncoming(_) => {
send_status(sender, e, error_handling::ErrorBranch::Break).await
}
Error::SubprotocolMining(_) => {
send_status(sender, e, error_handling::ErrorBranch::Break).await
}
Error::PoisonLock => send_status(sender, e, error_handling::ErrorBranch::Break).await,
Error::ChannelErrorReceiver(_) => {
send_status(sender, e, error_handling::ErrorBranch::Break).await
}
Error::TokioChannelErrorRecv(_) => {
send_status(sender, e, error_handling::ErrorBranch::Break).await
}
Error::ChannelErrorSender(_) => {
send_status(sender, e, error_handling::ErrorBranch::Break).await
}
Error::Uint256Conversion(_) => {
send_status(sender, e, error_handling::ErrorBranch::Break).await
}
Error::Infallible(_) => send_status(sender, e, error_handling::ErrorBranch::Break).await,
}
}