Skip to main content

tokio_actors/
error.rs

1//! Error types surfaced by the Tokio Actors runtime.
2
3use thiserror::Error;
4
5use crate::types::ActorId;
6
7/// Result type for actor operations.
8pub type ActorResult<T> = Result<T, ActorError>;
9
10/// Errors returned from user-defined actor logic.
11#[derive(Debug, Error, Clone)]
12pub enum ActorError {
13    /// A custom error message from the actor.
14    #[error("actor logic error: {0}")]
15    User(String),
16    /// The actor was cancelled.
17    #[error("actor cancelled")]
18    Cancelled,
19    /// The actor panicked during execution.
20    #[error("actor panicked: {0}")]
21    Panic(String),
22    /// A spawn error occurred.
23    #[error(transparent)]
24    Spawn(#[from] SpawnError),
25}
26
27impl ActorError {
28    /// Creates a new user-defined error.
29    pub fn user(message: impl Into<String>) -> Self {
30        Self::User(message.into())
31    }
32}
33
34impl From<TimerError> for ActorError {
35    fn from(value: TimerError) -> Self {
36        ActorError::User(value.to_string())
37    }
38}
39
40/// Failures encountered while sending a message asynchronously.
41#[derive(Debug, Error, Clone)]
42pub enum SendError {
43    /// The actor's mailbox is closed (actor stopped).
44    #[error("mailbox closed")]
45    Closed,
46}
47
48/// Failures encountered while sending without awaiting capacity.
49#[derive(Debug, Error, Clone)]
50pub enum TrySendError {
51    /// The mailbox is full.
52    #[error("mailbox full")]
53    Full,
54    /// The mailbox is closed (actor stopped).
55    #[error("mailbox closed")]
56    Closed,
57}
58
59/// Errors reported when awaiting a response from an actor.
60#[derive(Debug, Error, Clone)]
61pub enum AskError {
62    /// Failed to send the request.
63    #[error(transparent)]
64    Send(#[from] SendError),
65    /// The actor dropped the response channel without sending a reply.
66    #[error("response channel dropped")]
67    ResponseDropped,
68    /// The actor returned an error.
69    #[error("actor returned error: {0}")]
70    Actor(ActorError),
71}
72
73/// Failures encountered when spawning a child actor.
74#[derive(Debug, Error, Clone)]
75pub enum SpawnError {
76    /// No Tokio runtime was found in the current context.
77    #[error("tokio runtime handle not in scope")]
78    MissingRuntime,
79    /// A child with the same ID is already registered.
80    #[error("child actor `{0}` already registered")]
81    DuplicateChild(ActorId),
82    /// An actor with the given name is already registered in the system.
83    #[error("actor name `{name}` already taken in system `{system}`")]
84    NameTaken {
85        /// The actor name that was already taken.
86        name: String,
87        /// The system in which the collision occurred.
88        system: String,
89    },
90    /// An actor system with the given name already exists.
91    #[error("actor system `{0}` already exists")]
92    SystemNameTaken(String),
93}
94
95/// Errors emitted by the timer subsystem.
96#[derive(Debug, Error, Clone)]
97pub enum TimerError {
98    /// The specified timer ID was not found (already fired or cancelled).
99    #[error("timer id not found")]
100    NotFound,
101}
102
103/// Errors emitted by the stream subsystem.
104#[derive(Debug, Error, Clone)]
105pub enum StreamError {
106    /// The specified stream ID was not found (already finished or cancelled).
107    #[error("stream id not found")]
108    NotFound,
109}
110
111impl From<StreamError> for ActorError {
112    fn from(value: StreamError) -> Self {
113        ActorError::User(value.to_string())
114    }
115}
116
117/// Errors emitted by the supervision subsystem.
118#[derive(Debug, Error, Clone)]
119pub enum SupervisionError {
120    /// The specified child was not found.
121    #[error("child `{0}` not found")]
122    ChildNotFound(ActorId),
123    /// The restart budget has been exhausted.
124    #[error("restart budget exhausted")]
125    BudgetExhausted,
126    /// The factory closure failed during a restart attempt.
127    #[error("factory failed: {0}")]
128    FactoryFailed(String),
129    /// The actor is not configured as a supervisor.
130    #[error("actor is not configured as a supervisor")]
131    NotASupervisor,
132}
133
134impl From<SupervisionError> for ActorError {
135    fn from(value: SupervisionError) -> Self {
136        ActorError::User(value.to_string())
137    }
138}