Skip to main content

sysd_manager_comcontroler/
errors.rs

1use 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                //error message flatpak permission
54                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                //error message flatpak permission
61                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        //log::info!("TS {:?}", error);
179        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}