use crate::tokio::{sync::mpsc::error::SendError, time::error::Elapsed};
use core::fmt;
use ockam_core::{
compat::error::Error as StdError,
errcode::{Kind, Origin},
Address, Error,
};
#[allow(clippy::enum_variant_names)]
#[derive(Clone, Debug)]
pub enum NodeError {
Address(Address),
Data,
NodeState(NodeReason),
WorkerState(WorkerReason),
RouterState(RouterReason),
}
impl NodeError {
#[track_caller]
pub fn not_found(self) -> Error {
Error::new(Origin::Node, Kind::NotFound, self)
}
#[track_caller]
pub fn already_exists(self) -> Error {
Error::new(Origin::Node, Kind::AlreadyExists, self)
}
#[track_caller]
pub fn conflict(self) -> Error {
Error::new(Origin::Node, Kind::Conflict, self)
}
#[track_caller]
pub fn internal(self) -> Error {
Error::new(Origin::Node, Kind::Internal, self)
}
#[track_caller]
pub(crate) fn from_send_err<T: fmt::Debug>(err: SendError<T>) -> Error {
Error::new(
Origin::Node,
Kind::Internal,
NodeError::NodeState(NodeReason::Unknown),
)
.context("SendError", err)
}
#[track_caller]
pub(crate) fn with_elapsed(self, err: Elapsed) -> Error {
Error::new(Origin::Node, Kind::Timeout, err).context("Type", self)
}
}
impl StdError for NodeError {}
impl fmt::Display for NodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
match self {
Self::Address(addr) => format!("operation failed for address {}", addr),
Self::Data => "failed to load data".into(),
Self::NodeState(reason) => format!("failed because node state: {}", reason),
Self::WorkerState(reason) => format!("failed because worker state: {}", reason),
Self::RouterState(reason) => format!("failed because router state: {}", reason),
}
)
}
}
#[allow(clippy::enum_variant_names)]
#[derive(Clone, Copy, Debug)]
pub enum RouterReason {
Duplicate,
InvalidAddrType,
EmptyAddressSet,
}
impl fmt::Display for RouterReason {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
match self {
Self::Duplicate => "a router for this type already exists",
Self::InvalidAddrType => "you can not register router for this address type",
Self::EmptyAddressSet => "address set cannot be empty",
}
)
}
}
#[allow(clippy::enum_variant_names)]
#[derive(Clone, Copy, Debug)]
pub enum NodeReason {
Unknown,
Shutdown,
Corrupt,
}
impl fmt::Display for NodeReason {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
match self {
Self::Unknown => "unknown node state",
Self::Shutdown => "ockam node is shutting down",
Self::Corrupt => "ockam node is corrupt and can not be recovered",
}
)
}
}
#[allow(clippy::enum_variant_names)]
#[derive(Clone, Copy, Debug)]
pub enum WorkerReason {
Shutdown,
Faulty,
Corrupt,
}
impl fmt::Display for WorkerReason {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
match self {
Self::Shutdown => "target worker is shutting down",
Self::Faulty => "target worker is faulty and waiting for supervisor",
Self::Corrupt => "target worker is corrupt and can not be recovered",
}
)
}
}