1use crate::tokio::sync::mpsc::error::SendError;
2use core::fmt;
3use core::time::Duration;
4use ockam_core::{
5 compat::error::Error as StdError,
6 errcode::{Kind, Origin},
7 Address, Error,
8};
9
10#[allow(clippy::enum_variant_names)]
12#[derive(Clone, Debug)]
13pub enum NodeError {
14 Address(Address),
18 Data,
20 NodeState(NodeReason),
22 WorkerState(WorkerReason),
24 RouterState(RouterReason),
26}
27
28impl NodeError {
29 #[track_caller]
31 pub fn not_found(self) -> Error {
32 Error::new(Origin::Node, Kind::NotFound, self)
33 }
34 #[track_caller]
36 pub fn already_exists(self) -> Error {
37 Error::new(Origin::Node, Kind::AlreadyExists, self)
38 }
39 #[track_caller]
41 pub fn conflict(self) -> Error {
42 Error::new(Origin::Node, Kind::Conflict, self)
43 }
44 #[track_caller]
46 pub fn internal(self) -> Error {
47 Error::new(Origin::Node, Kind::Internal, self)
48 }
49 #[track_caller]
51 pub(crate) fn from_send_err<T: fmt::Debug>(err: SendError<T>) -> Error {
52 Error::new(
53 Origin::Node,
54 Kind::Internal,
55 NodeError::NodeState(NodeReason::Unknown),
56 )
57 .context("SendError", err)
58 }
59
60 #[track_caller]
62 pub(crate) fn with_timeout(self, duration: Duration) -> Error {
63 Error::new(
64 Origin::Node,
65 Kind::Timeout,
66 format!("timeout: {duration:?}"),
67 )
68 .context("Type", self)
69 }
70}
71
72impl StdError for NodeError {}
73
74impl fmt::Display for NodeError {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 write!(
77 f,
78 "{}",
79 match self {
80 Self::Address(addr) => format!("operation failed for address {}", addr),
81 Self::Data => "failed to load data".into(),
82 Self::NodeState(reason) => format!("failed because node state: {}", reason),
83 Self::WorkerState(reason) => format!("failed because worker state: {}", reason),
84 Self::RouterState(reason) => format!("failed because router state: {}", reason),
85 }
86 )
87 }
88}
89
90#[allow(clippy::enum_variant_names)]
92#[derive(Clone, Copy, Debug)]
93pub enum RouterReason {
94 Duplicate,
96 InvalidAddrType,
98 EmptyAddressSet,
100}
101
102impl fmt::Display for RouterReason {
103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 write!(
105 f,
106 "{}",
107 match self {
108 Self::Duplicate => "a router for this type already exists",
109 Self::InvalidAddrType => "you can not register router for this address type",
110 Self::EmptyAddressSet => "address set cannot be empty",
111 }
112 )
113 }
114}
115
116#[allow(clippy::enum_variant_names)]
120#[derive(Clone, Copy, Debug)]
121pub enum NodeReason {
122 Unknown,
127 Shutdown,
129 Corrupt,
131}
132
133impl fmt::Display for NodeReason {
134 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135 write!(
136 f,
137 "{}",
138 match self {
139 Self::Unknown => "unknown node state",
140 Self::Shutdown => "ockam node is shutting down",
141 Self::Corrupt => "ockam node is corrupt and can not be recovered",
142 }
143 )
144 }
145}
146
147#[allow(clippy::enum_variant_names)]
149#[derive(Clone, Copy, Debug)]
150pub enum WorkerReason {
151 Shutdown,
153 Faulty,
155 Corrupt,
157 CtrlChannelError,
159}
160
161impl fmt::Display for WorkerReason {
162 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
163 write!(
164 f,
165 "{}",
166 match self {
167 Self::Shutdown => "target worker is shutting down",
168 Self::Faulty => "target worker is faulty and waiting for supervisor",
169 Self::Corrupt => "target worker is corrupt and can not be recovered",
170 Self::CtrlChannelError => "target worker cannot receive shutdown signal",
171 }
172 )
173 }
174}