1use std::fmt::Display;
9
10use crate::ActorName;
11
12pub type ActorProcessingErr = Box<dyn std::error::Error + Send + Sync + 'static>;
14
15#[derive(Debug)]
17pub enum SpawnErr {
18 StartupFailed(ActorProcessingErr),
20 ActorAlreadyStarted,
22 ActorAlreadyRegistered(ActorName),
24}
25
26impl std::error::Error for SpawnErr {
27 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
28 match &self {
29 Self::StartupFailed(inner) => Some(inner.as_ref()),
30 _ => None,
31 }
32 }
33}
34
35impl Display for SpawnErr {
36 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37 match self {
38 Self::StartupFailed(panic_msg) => {
39 if f.alternate() {
40 write!(f, "Actor panicked during startup '{panic_msg:#}'")
41 } else {
42 write!(f, "Actor panicked during startup '{panic_msg}'")
43 }
44 }
45 Self::ActorAlreadyStarted => {
46 write!(f, "Actor cannot be re-started more than once")
47 }
48 Self::ActorAlreadyRegistered(actor_name) => {
49 write!(
50 f,
51 "Actor '{actor_name}' is already registered in the actor registry"
52 )
53 }
54 }
55 }
56}
57
58impl From<crate::registry::ActorRegistryErr> for SpawnErr {
59 fn from(value: crate::registry::ActorRegistryErr) -> Self {
60 match value {
61 crate::registry::ActorRegistryErr::AlreadyRegistered(actor_name) => {
62 SpawnErr::ActorAlreadyRegistered(actor_name)
63 }
64 }
65 }
66}
67
68#[derive(Debug)]
70pub enum ActorErr {
71 Cancelled,
73 Failed(ActorProcessingErr),
75}
76
77impl std::error::Error for ActorErr {
78 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
79 match &self {
80 Self::Failed(inner) => Some(inner.as_ref()),
81 _ => None,
82 }
83 }
84}
85
86impl Display for ActorErr {
87 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88 match self {
89 Self::Failed(panic_msg) => {
90 if f.alternate() {
91 write!(f, "Actor panicked '{panic_msg:#}'")
92 } else {
93 write!(f, "Actor panicked '{panic_msg}'")
94 }
95 }
96 Self::Cancelled => {
97 write!(f, "Actor operation cancelled")
98 }
99 }
100 }
101}
102
103pub enum MessagingErr<T> {
105 SendErr(T),
112
113 ChannelClosed,
116
117 InvalidActorType,
121}
122
123impl<T> MessagingErr<T> {
124 pub fn map<F, U>(self, mapper: F) -> MessagingErr<U>
127 where
128 F: FnOnce(T) -> U,
129 {
130 match self {
131 MessagingErr::SendErr(err) => MessagingErr::SendErr(mapper(err)),
132 MessagingErr::ChannelClosed => MessagingErr::ChannelClosed,
133 MessagingErr::InvalidActorType => MessagingErr::InvalidActorType,
134 }
135 }
136}
137
138impl<T> std::fmt::Debug for MessagingErr<T> {
139 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
140 match self {
141 Self::SendErr(_) => write!(f, "SendErr"),
142 Self::ChannelClosed => write!(f, "RecvErr"),
143 Self::InvalidActorType => write!(f, "InvalidActorType"),
144 }
145 }
146}
147
148impl<T> std::error::Error for MessagingErr<T> {}
151
152#[allow(unsafe_code)]
157unsafe impl<T> Sync for MessagingErr<T> {}
158
159impl<T> From<tokio::sync::mpsc::error::SendError<T>> for MessagingErr<T> {
160 fn from(e: tokio::sync::mpsc::error::SendError<T>) -> Self {
161 Self::SendErr(e.0)
162 }
163}
164impl<T> From<tokio::sync::mpsc::error::TrySendError<T>> for MessagingErr<T> {
165 fn from(e: tokio::sync::mpsc::error::TrySendError<T>) -> Self {
166 match e {
167 tokio::sync::mpsc::error::TrySendError::Closed(c) => Self::SendErr(c),
168 tokio::sync::mpsc::error::TrySendError::Full(c) => Self::SendErr(c),
169 }
170 }
171}
172
173impl<T> Display for MessagingErr<T> {
174 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
175 match self {
176 Self::ChannelClosed => {
177 write!(f, "Messaging failed because channel is closed")
178 }
179 Self::InvalidActorType => {
180 write!(f, "Messaging failed due to the provided actor type not matching the actor's properties")
181 }
182 Self::SendErr(_) => {
183 write!(f, "Messaging failed to enqueue the message to the specified actor, the actor is likely terminated")
184 }
185 }
186 }
187}
188
189pub enum RactorErr<T> {
191 Spawn(SpawnErr),
193 Messaging(MessagingErr<T>),
195 Actor(ActorErr),
197 Timeout,
199}
200
201impl<T> RactorErr<T> {
202 pub fn has_message(&self) -> bool {
208 matches!(self, Self::Messaging(MessagingErr::SendErr(_)))
209 }
210 pub fn try_get_message(self) -> Option<T> {
216 if let Self::Messaging(MessagingErr::SendErr(msg)) = self {
217 Some(msg)
218 } else {
219 None
220 }
221 }
222
223 pub fn map<F, U>(self, mapper: F) -> RactorErr<U>
226 where
227 F: FnOnce(T) -> U,
228 {
229 match self {
230 RactorErr::Spawn(err) => RactorErr::Spawn(err),
231 RactorErr::Messaging(err) => RactorErr::Messaging(err.map(mapper)),
232 RactorErr::Actor(err) => RactorErr::Actor(err),
233 RactorErr::Timeout => RactorErr::Timeout,
234 }
235 }
236}
237
238impl<T> std::fmt::Debug for RactorErr<T> {
239 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
240 match self {
241 Self::Messaging(m) => write!(f, "Messaging({m:?})"),
242 Self::Actor(a) => write!(f, "Actor({a:?})"),
243 Self::Spawn(s) => write!(f, "Spawn({s:?})"),
244 Self::Timeout => write!(f, "Timeout"),
245 }
246 }
247}
248
249impl<T> std::error::Error for RactorErr<T> {}
250
251impl<T> From<SpawnErr> for RactorErr<T> {
252 fn from(value: SpawnErr) -> Self {
253 RactorErr::Spawn(value)
254 }
255}
256
257impl<T> From<MessagingErr<T>> for RactorErr<T> {
258 fn from(value: MessagingErr<T>) -> Self {
259 RactorErr::Messaging(value)
260 }
261}
262
263impl<T> From<ActorErr> for RactorErr<T> {
264 fn from(value: ActorErr) -> Self {
265 RactorErr::Actor(value)
266 }
267}
268
269impl<T, TResult> From<crate::rpc::CallResult<TResult>> for RactorErr<T> {
270 fn from(value: crate::rpc::CallResult<TResult>) -> Self {
271 match value {
272 crate::rpc::CallResult::SenderError => {
273 RactorErr::Messaging(MessagingErr::ChannelClosed)
274 }
275 crate::rpc::CallResult::Timeout => RactorErr::Timeout,
276 _ => panic!("A successful `CallResult` cannot be mapped to a `RactorErr`"),
277 }
278 }
279}
280
281impl<T> std::fmt::Display for RactorErr<T> {
282 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
283 match self {
284 Self::Actor(actor_err) => {
285 if f.alternate() {
286 write!(f, "{actor_err:#}")
287 } else {
288 write!(f, "{actor_err}")
289 }
290 }
291 Self::Messaging(messaging_err) => {
292 if f.alternate() {
293 write!(f, "{messaging_err:#}")
294 } else {
295 write!(f, "{messaging_err}")
296 }
297 }
298 Self::Spawn(spawn_err) => {
299 if f.alternate() {
300 write!(f, "{spawn_err:#}")
301 } else {
302 write!(f, "{spawn_err}")
303 }
304 }
305 Self::Timeout => {
306 write!(f, "timeout")
307 }
308 }
309 }
310}