1use thiserror::Error;
3
4#[derive(Debug, Error)]
6pub enum ProcessManagerError {
7 #[error("Failed to read config file: {0}")]
9 ConfigReadError(#[from] std::io::Error),
10
11 #[error("Invalid YAML format: {0}")]
13 ConfigParseError(#[from] serde_yaml::Error),
14
15 #[error("Failed to start service '{service}': {source}")]
17 ServiceStartError {
18 service: String,
20 #[source]
22 source: std::io::Error,
23 },
24
25 #[error("Failed to stop service '{service}': {source}")]
27 ServiceStopError {
28 service: String,
30 #[source]
32 source: std::io::Error,
33 },
34
35 #[error("Failed to execute hook for service '{service}': {source}")]
37 HookExecutionError {
38 service: String,
40 #[source]
42 source: std::io::Error,
43 },
44
45 #[error(
47 "Service '{service}' is waiting for an unavailable dependency: '{dependency}'"
48 )]
49 DependencyError {
50 service: String,
52 dependency: String,
54 },
55
56 #[error("Service '{service}' cannot start because dependency '{dependency}' failed")]
58 DependencyFailed {
59 service: String,
61 dependency: String,
63 },
64
65 #[error("Service '{service}' declares unknown dependency '{dependency}'")]
67 UnknownDependency {
68 service: String,
70 dependency: String,
72 },
73
74 #[error("Detected dependency cycle: {cycle}")]
76 DependencyCycle {
77 cycle: String,
79 },
80
81 #[error("Mutex is poisoned: {0}")]
83 MutexPoisonError(String),
84
85 #[error("PID file error: {0}")]
87 PidFileError(#[from] PidFileError),
88
89 #[error("Service state error: {0}")]
91 ServiceStateError(#[from] ServiceStateError),
92
93 #[error("Service not found in PID file")]
95 ErrNo(#[from] nix::errno::Errno),
96
97 #[error("Failed to configure privileges for service '{service}': {source}")]
99 PrivilegeSetupFailed {
100 service: String,
102 #[source]
104 source: std::io::Error,
105 },
106
107 #[error("Service(s) failed to remain running after restart: {services:?}")]
109 ServicesNotRunning {
110 services: Vec<String>,
112 },
113}
114
115impl<T> From<std::sync::PoisonError<T>> for ProcessManagerError {
117 fn from(err: std::sync::PoisonError<T>) -> Self {
119 ProcessManagerError::MutexPoisonError(err.to_string())
120 }
121}
122
123#[derive(Debug, Error)]
125pub enum PidFileError {
126 #[error("Failed to read PID file: {0}")]
128 ReadError(#[from] std::io::Error),
129
130 #[error("Failed to parse PID file: {0}")]
132 ParseError(#[from] serde_json::Error),
133
134 #[error("Service not found in PID file")]
136 ServiceNotFound,
137}
138
139#[derive(Debug, Error)]
141pub enum ServiceStateError {
142 #[error("Failed to read service state file: {0}")]
144 ReadError(#[from] std::io::Error),
145
146 #[error("Failed to parse service state file: {0}")]
148 ParseError(#[from] serde_json::Error),
149
150 #[error("Service not found in state file")]
152 ServiceNotFound,
153}
154
155#[derive(Debug, Error)]
157pub enum LogsManagerError {
158 #[error("Service '{0}' not found in PID file")]
160 ServiceNotFound(String),
161
162 #[error("Log file unavailable for PID {0}")]
164 LogUnavailable(u32),
165
166 #[error("Log tailing failed: {0}")]
168 LogProcessError(#[from] std::io::Error),
169
170 #[error("Log tail command exited with status {0:?}")]
172 TailCommandFailed(Option<i32>),
173
174 #[error("Unsupported platform for log tailing")]
176 UnsupportedPlatform,
177}