Skip to main content

appcore_supervisor/
error.rs

1// =============================================================================
2//        #######
3//     ###       ###     F: error.rs
4//    ##   ## ##   ##    P: AppCore-Runtime
5//         ## ##
6//                       C: 2026/07/24 11:51:10 by dnettoRaw
7//    ##   ## ##   ##    U: 2026/07/24 13:18:47 by dnettoRaw
8//      ###########      S: 1.0.1-rc.8
9// =============================================================================
10
11//! Controlled supervisor failures.
12
13use std::fmt::{Display, Formatter};
14
15/// Result returned by supervisor operations.
16pub type SupervisorResult<T> = Result<T, SupervisorError>;
17
18/// Controlled failure produced by service supervision.
19#[derive(Debug, Clone, PartialEq, Eq)]
20pub enum SupervisorError {
21    /// A service name or policy is invalid.
22    InvalidConfiguration(String),
23    /// A service is already registered.
24    ServiceAlreadyRegistered(String),
25    /// A requested service is absent.
26    ServiceNotFound(String),
27    /// A declared dependency is absent.
28    DependencyNotFound {
29        /// Dependent service.
30        service: String,
31        /// Missing dependency.
32        dependency: String,
33    },
34    /// The dependency graph contains a cycle.
35    DependencyCycle(Vec<String>),
36    /// A required dependency is not ready.
37    DependencyUnavailable {
38        /// Dependent service.
39        service: String,
40        /// Unavailable dependency.
41        dependency: String,
42    },
43    /// A managed service boundary failed.
44    ServiceFailure {
45        /// Service that failed.
46        service: String,
47        /// Redacted controlled reason.
48        reason: String,
49    },
50    /// A service did not stop inside its configured deadline.
51    ShutdownTimeout(String),
52    /// A previous service instance still owns its resource.
53    ServiceOrphaned(String),
54    /// The temporal restart budget was exhausted.
55    RestartBudgetExceeded(String),
56    /// The bounded restart queue cannot accept more work.
57    RestartQueueFull,
58    /// The restart executor is stopping or unavailable.
59    RestartExecutorStopped,
60    /// Shared supervisor state was poisoned.
61    StatePoisoned,
62}
63
64impl Display for SupervisorError {
65    fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
66        match self {
67            Self::InvalidConfiguration(reason) => {
68                write!(formatter, "invalid supervisor configuration: {reason}")
69            }
70            Self::ServiceAlreadyRegistered(service) => {
71                write!(formatter, "service `{service}` is already registered")
72            }
73            Self::ServiceNotFound(service) => {
74                write!(formatter, "service `{service}` is not registered")
75            }
76            Self::DependencyNotFound {
77                service,
78                dependency,
79            } => write!(
80                formatter,
81                "service `{service}` requires missing dependency `{dependency}`"
82            ),
83            Self::DependencyCycle(cycle) => {
84                write!(
85                    formatter,
86                    "service dependency cycle: {}",
87                    cycle.join(" -> ")
88                )
89            }
90            Self::DependencyUnavailable {
91                service,
92                dependency,
93            } => write!(
94                formatter,
95                "service `{service}` dependency `{dependency}` is unavailable"
96            ),
97            Self::ServiceFailure { service, reason } => {
98                write!(formatter, "service `{service}` failed: {reason}")
99            }
100            Self::ShutdownTimeout(service) => {
101                write!(
102                    formatter,
103                    "service `{service}` exceeded its shutdown timeout"
104                )
105            }
106            Self::ServiceOrphaned(service) => {
107                write!(
108                    formatter,
109                    "service `{service}` has an orphaned instance and cannot start"
110                )
111            }
112            Self::RestartBudgetExceeded(service) => {
113                write!(
114                    formatter,
115                    "service `{service}` exhausted its restart budget"
116                )
117            }
118            Self::RestartQueueFull => formatter.write_str("restart executor queue is full"),
119            Self::RestartExecutorStopped => formatter.write_str("restart executor is unavailable"),
120            Self::StatePoisoned => formatter.write_str("supervisor state is poisoned"),
121        }
122    }
123}
124
125impl std::error::Error for SupervisorError {}