sysd_manager_comcontroler/
errors.rs1use std::{
2 ffi::OsString,
3 fmt::{self, Display, Formatter},
4 string::FromUtf8Error,
5};
6
7use base::file::SysdBaseError;
8use gettextrs::pgettext;
9
10#[derive(Debug)]
11#[allow(unused)]
12pub enum SystemdErrors {
13 Command(
14 OsString,
15 Vec<OsString>,
16 Vec<(OsString, Option<OsString>)>,
17 std::io::Error,
18 ),
19 Custom(String),
20 IoError(std::io::Error),
21 Utf8Error(FromUtf8Error),
22 Fmt(std::fmt::Error),
23 ZMethodError(String, String, String),
24 CmdNoFlatpakSpawn,
25 CmdNoFreedesktopFlatpakPermission(Option<String>, Option<String>),
26 JournalError(String),
27 NoFilePathforUnit(String),
28 Malformed(String, String),
29 NotAuthorized,
30 NotAuthorizedAuthentificationDismissed,
31 NoUnit,
32 SystemCtlError(String),
33 Tokio,
34 ZBusError(zbus::Error),
35 ZAccessDenied(String, String),
36 ZNoSuchUnit(String, String),
37 ZNoSuchUnitProxy(String, String),
38 ZJobTypeNotApplicable(String, String),
39 ZUnitMasked(String, String),
40 ZVariantError(zvariant::Error),
41 ZBusFdoError(zbus::fdo::Error),
42 ZFdoServiceUnknowm(String),
43 ZFdoZError(String),
44 ZXml(zbus_xml::Error),
45 Unreachable,
46 InvalidPath(String),
47}
48
49impl SystemdErrors {
50 pub fn gui_description(&self) -> Option<String> {
51 match self {
52 SystemdErrors::CmdNoFlatpakSpawn => {
53 Some(pgettext(
55 "error",
56 "The program <b>flatpack-spawn</b> is needed if you use the application from Flatpack.\nPlease install it to enable all features.",
57 ))
58 }
59 SystemdErrors::CmdNoFreedesktopFlatpakPermission(_cmdl, _file_path) => {
60 Some(pgettext(
62 "error",
63 "It requires permission to talk to <b>org.freedesktop.Flatpak</b> D-Bus interface when the program is a Flatpak.",
64 ))
65 }
66 _ => None,
67 }
68 }
69
70 pub fn human_error_type(&self) -> String {
71 match self {
72 SystemdErrors::ZAccessDenied(_, detail) => detail.clone(),
73 SystemdErrors::ZJobTypeNotApplicable(_, detail) => detail.clone(),
74 SystemdErrors::ZNoSuchUnit(_, detail) => detail.clone(),
75 SystemdErrors::ZNoSuchUnitProxy(_, detail) => detail.clone(),
76 SystemdErrors::ZUnitMasked(_, detail) => detail.clone(),
77 _ => self.to_string(),
78 }
79 }
80
81 pub fn file_not_found(&self) -> bool {
82 if let SystemdErrors::IoError(io_error) = self
83 && io_error.kind() == std::io::ErrorKind::NotFound
84 {
85 true
86 } else {
87 false
88 }
89 }
90}
91
92impl Display for SystemdErrors {
93 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
94 write!(f, "{self:?}")
95 }
96}
97
98impl From<std::io::Error> for SystemdErrors {
99 fn from(error: std::io::Error) -> Self {
100 SystemdErrors::IoError(error)
101 }
102}
103
104impl From<FromUtf8Error> for SystemdErrors {
105 fn from(error: FromUtf8Error) -> Self {
106 SystemdErrors::Utf8Error(error)
107 }
108}
109
110impl From<(zbus::Error, &str)> for SystemdErrors {
111 fn from(value: (zbus::Error, &str)) -> Self {
112 let (zb_error, method) = value;
113
114 match zb_error {
115 zbus::Error::MethodError(owned_error_name, ref msg, _message) => {
116 let err_code = zvariant::Str::from(owned_error_name);
117
118 let err_code = err_code.as_str();
119 let message = msg.clone().unwrap_or_default();
120
121 match err_code {
122 "org.freedesktop.DBus.Error.AccessDenied" => {
123 let method = if method.is_empty() {
124 "AccessDenied"
125 } else {
126 method
127 };
128 SystemdErrors::ZAccessDenied(method.to_owned(), message)
129 }
130 "org.freedesktop.systemd1.NoSuchUnit" => {
131 let method = if method.is_empty() {
132 "NoSuchUnit"
133 } else {
134 method
135 };
136 SystemdErrors::ZNoSuchUnit(method.to_owned(), message)
137 }
138 "org.freedesktop.DBus.Error.InvalidArgs" => {
139 let method = if method.is_empty() {
140 "InvalidArgs"
141 } else {
142 method
143 };
144 SystemdErrors::ZNoSuchUnitProxy(method.to_owned(), message)
145 }
146 "org.freedesktop.systemd1.JobTypeNotApplicable" => {
147 let method = if method.is_empty() {
148 "JobTypeNotApplicable"
149 } else {
150 method
151 };
152 SystemdErrors::ZJobTypeNotApplicable(method.to_owned(), message)
153 }
154 "org.freedesktop.systemd1.UnitMasked" => {
155 let method = if method.is_empty() {
156 "UnitMasked"
157 } else {
158 method
159 };
160 SystemdErrors::ZUnitMasked(method.to_owned(), message)
161 }
162 "org.freedesktop.zbus.Error" => {
163 SystemdErrors::ZUnitMasked(method.to_owned(), message)
164 }
165 _ => {
166 SystemdErrors::ZMethodError(method.to_owned(), err_code.to_owned(), message)
167 }
168 }
169 }
170
171 _ => SystemdErrors::ZBusError(zb_error),
172 }
173 }
174}
175
176impl From<zbus::Error> for SystemdErrors {
177 fn from(error: zbus::Error) -> Self {
178 SystemdErrors::from((error, ""))
180 }
181}
182
183impl From<zbus::fdo::Error> for SystemdErrors {
184 fn from(error: zbus::fdo::Error) -> Self {
185 match error {
186 zbus::fdo::Error::ServiceUnknown(s) => SystemdErrors::ZFdoServiceUnknowm(s),
187 zbus::fdo::Error::ZBus(err) => err.into(),
188 _ => SystemdErrors::ZBusFdoError(error),
189 }
190 }
191}
192
193impl From<Box<dyn std::error::Error>> for SystemdErrors {
194 fn from(error: Box<dyn std::error::Error>) -> Self {
195 let msg = format!("{error}");
196 SystemdErrors::JournalError(msg)
197 }
198}
199
200impl From<zvariant::Error> for SystemdErrors {
201 fn from(value: zvariant::Error) -> Self {
202 SystemdErrors::ZVariantError(value)
203 }
204}
205
206impl From<tokio::task::JoinError> for SystemdErrors {
207 fn from(_value: tokio::task::JoinError) -> Self {
208 SystemdErrors::Tokio
209 }
210}
211
212impl From<zbus_xml::Error> for SystemdErrors {
213 fn from(value: zbus_xml::Error) -> Self {
214 SystemdErrors::ZXml(value)
215 }
216}
217
218impl From<std::fmt::Error> for SystemdErrors {
219 fn from(value: std::fmt::Error) -> Self {
220 SystemdErrors::Fmt(value)
221 }
222}
223
224impl From<String> for SystemdErrors {
225 fn from(value: String) -> Self {
226 SystemdErrors::Custom(value)
227 }
228}
229
230impl From<&str> for SystemdErrors {
231 fn from(value: &str) -> Self {
232 value.to_owned().into()
233 }
234}
235
236impl From<SysdBaseError> for SystemdErrors {
237 fn from(value: SysdBaseError) -> Self {
238 match value {
239 SysdBaseError::CmdNoFreedesktopFlatpakPermission => {
240 SystemdErrors::CmdNoFreedesktopFlatpakPermission(None, None)
241 }
242 SysdBaseError::CommandCallError(os_string, os_strings, items, error) => {
243 SystemdErrors::Command(os_string, os_strings, items, error)
244 }
245 SysdBaseError::Custom(s) => SystemdErrors::Custom(s),
246 SysdBaseError::IoError(error) => SystemdErrors::IoError(error),
247 SysdBaseError::NotAuthorizedAuthentificationDismissed => {
248 SystemdErrors::NotAuthorizedAuthentificationDismissed
249 }
250 SysdBaseError::NotAuthorized => SystemdErrors::NotAuthorized,
251 SysdBaseError::Tokio(_join_error) => SystemdErrors::Tokio,
252 SysdBaseError::InvalidPath(msg) => SystemdErrors::InvalidPath(msg),
253 }
254 }
255}