aion_server/worker/supervisor/
error.rs1use thiserror::Error;
9
10use super::policy::UNCOMMISSIONED_REMEDY;
11
12#[derive(Debug, Error)]
14pub enum SupervisionError {
15 #[error("{UNCOMMISSIONED_REMEDY}")]
17 NotCommissioned,
18 #[error(
20 "worker deployment `{name}` was not found; create it first with a PUT to /worker-deployments/{name}"
21 )]
22 UnknownDeployment {
23 name: String,
25 },
26 #[error("worker deployment store failed: {source}")]
28 Store {
29 #[source]
31 source: aion_store::StoreError,
32 },
33 #[error("could not resolve the running server executable: {detail}")]
35 ExecutableUnresolved {
36 detail: String,
38 },
39 #[error("could not read managed worker executable `{path}`: {detail}")]
41 ExecutableUnreadable {
42 path: String,
44 detail: String,
46 },
47 #[error("managed worker `{name}` process failed: {source}")]
49 Process {
50 name: String,
52 #[source]
54 source: aion_worker::ProcessGroupError,
55 },
56 #[error("managed worker `{name}` could not be confirmed stopped: {detail}")]
63 StopIncomplete {
64 name: String,
66 detail: String,
68 },
69 #[error("managed worker `{name}` supervision task ended abnormally: {detail}")]
71 TaskLost {
72 name: String,
74 detail: String,
76 },
77 #[error("managed worker supervision state is poisoned: {detail}")]
79 StatePoisoned {
80 detail: String,
82 },
83}
84
85impl SupervisionError {
86 #[must_use]
88 pub const fn remedy(&self) -> Option<&'static str> {
89 match self {
90 Self::NotCommissioned => Some(UNCOMMISSIONED_REMEDY),
91 _ => None,
92 }
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::SupervisionError;
99
100 #[test]
103 fn the_uncommissioned_refusal_names_the_section_and_every_required_key() {
104 let message = SupervisionError::NotCommissioned.to_string();
105 for expected in [
106 "[worker_supervision]",
107 "restart_backoff_initial_ms",
108 "restart_backoff_max_ms",
109 "restart_backoff_multiplier",
110 "restart_window_ms",
111 "max_restarts_per_window",
112 "stop_grace_ms",
113 ] {
114 assert!(
115 message.contains(expected),
116 "the refusal must name `{expected}`: {message}"
117 );
118 }
119 assert_eq!(
120 SupervisionError::NotCommissioned.remedy(),
121 Some(super::UNCOMMISSIONED_REMEDY)
122 );
123 }
124
125 #[test]
126 fn an_unknown_deployment_refusal_names_the_deployment_and_the_way_to_create_it() {
127 let message = SupervisionError::UnknownDeployment {
128 name: "shells".to_owned(),
129 }
130 .to_string();
131 assert!(message.contains("shells"));
132 assert!(message.contains("/worker-deployments/shells"));
133 }
134}