1use std::{
10 array::TryFromSliceError,
11 env::VarError,
12 fmt, io,
13 net::AddrParseError,
14 num::{ParseIntError, TryFromIntError},
15 str::Utf8Error,
16};
17
18#[cfg(feature = "oci")]
19use libcgroups::common::AnyManagerError;
20#[cfg(feature = "oci")]
21use libcgroups::common::CreateCgroupSetupError;
22#[cfg(feature = "oci")]
23use libcontainer::error::LibcontainerError;
24#[cfg(feature = "oci")]
25use libcontainer::signal::SignalError;
26#[cfg(feature = "oci")]
27use libcontainer::utils::PathBufExtError;
28use nix::errno::Errno;
29use procfs::ProcError;
30use shellexpand::LookupError;
31#[cfg(feature = "oci")]
32use tracing::subscriber::SetGlobalDefaultError;
33
34use crate::{caps::errors::CapsError, elf::ElfError, libseccomp::error::SeccompError};
35
36pub type SydResult<T> = std::result::Result<T, SydError>;
38
39#[macro_export]
41macro_rules! lasterrno {
42 () => {
43 SydError::Nix(nix::errno::Errno::last())
44 };
45}
46
47pub enum SydError {
49 Addr(AddrParseError),
51 Args(lexopt::Error),
53 Caps(CapsError),
55 Elf(ElfError),
57 Env(LookupError<VarError>),
59 Nix(Errno),
61 Json(serde_json::Error),
63 ParseInt(ParseIntError),
65 TryInt(TryFromIntError),
67 TrySlice(TryFromSliceError),
69 ParseSize(parse_size::Error),
71 Proc(ProcError),
73 Regex(regex::Error),
75 Scmp(SeccompError),
77 Utf8(Utf8Error),
79 #[cfg(feature = "oci")]
80 CgSetup(CreateCgroupSetupError),
82 #[cfg(feature = "oci")]
83 CgMisc(AnyManagerError),
85 #[cfg(feature = "oci")]
86 Cont(LibcontainerError),
88 #[cfg(feature = "oci")]
89 Pext(PathBufExtError),
91 #[cfg(feature = "oci")]
92 SetTracing(SetGlobalDefaultError),
94 #[cfg(feature = "oci")]
95 Signal(SignalError<String>),
97 #[cfg(feature = "oci")]
98 Spec(oci_spec::OciSpecError),
100}
101
102impl SydError {
103 #[inline(always)]
105 pub fn errno(&self) -> Option<Errno> {
106 match self {
107 Self::Nix(errno) => Some(*errno),
108 Self::Proc(error) => proc_error_to_errno(error),
109 Self::Scmp(error) => error
110 .sysrawrc()
111 .map(|errno| errno.abs())
112 .map(Errno::from_raw),
113 _ => None,
114 }
115 }
116}
117
118impl fmt::Debug for SydError {
119 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
120 match self {
121 Self::Addr(error) => write!(f, "AddrParseError: {error:?}"),
122 Self::Args(error) => write!(f, "ArgsParseError: {error:?}"),
123 Self::Caps(error) => write!(f, "CapsError: {error:?}"),
124 Self::Elf(error) => write!(f, "ElfError: {error:?}"),
125 Self::Env(error) => write!(f, "LookupError<VarError>: {error:?}"),
126 Self::Nix(errno) => write!(f, "NixError: {errno:?}"),
127 Self::Json(error) => write!(f, "JsonError: {error:?}"),
128 Self::ParseInt(error) => write!(f, "ParseIntError: {error:?}"),
129 Self::Scmp(error) => write!(f, "SeccompError: {error:?}"),
130 Self::TryInt(error) => write!(f, "TryFromIntError: {error:?}"),
131 Self::TrySlice(error) => write!(f, "TryFromSliceError: {error:?}"),
132 Self::ParseSize(error) => write!(f, "ParseSizeError: {error:?}"),
133 Self::Proc(error) => write!(f, "ProcError: {error:?}"),
134 Self::Regex(error) => write!(f, "RegexError: {error:?}"),
135 Self::Utf8(error) => write!(f, "Utf8Error: {error:?}"),
136 #[cfg(feature = "oci")]
137 Self::CgSetup(error) => write!(f, "CgroupSetupError: {error:?}"),
138 #[cfg(feature = "oci")]
139 Self::CgMisc(error) => write!(f, "AnyManagerError: {error:?}"),
140 #[cfg(feature = "oci")]
141 Self::Cont(error) => write!(f, "ContainerError: {error:?}"),
142 #[cfg(feature = "oci")]
143 Self::Pext(error) => write!(f, "PathBufExtError: {error:?}"),
144 #[cfg(feature = "oci")]
145 Self::SetTracing(error) => write!(f, "SetGlobalDefaultError: {error:?}"),
146 #[cfg(feature = "oci")]
147 Self::Signal(error) => write!(f, "SignalError: {error:?}"),
148 #[cfg(feature = "oci")]
149 Self::Spec(error) => write!(f, "OciSpecError: {error:?}"),
150 }
151 }
152}
153
154impl fmt::Display for SydError {
155 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
156 match self {
157 Self::Addr(error) => write!(f, "AddrParseError: {error}"),
158 Self::Args(error) => write!(f, "ArgsParseError: {error}"),
159 Self::Caps(error) => write!(f, "CapsError: {error}"),
160 Self::Elf(error) => write!(f, "ElfError: {error}"),
161 Self::Env(error) => write!(f, "LookupError<VarError>: {error}"),
162 Self::Nix(errno) => write!(f, "NixError: {errno}"),
163 Self::Json(error) => write!(f, "JsonError: {error}"),
164 Self::ParseInt(error) => write!(f, "ParseIntError: {error}"),
165 Self::Scmp(error) => write!(f, "SeccompError: {error}"),
166 Self::TryInt(error) => write!(f, "TryFromIntError: {error}"),
167 Self::TrySlice(error) => write!(f, "TryFromSliceError: {error}"),
168 Self::ParseSize(error) => write!(f, "ParseSizeError: {error}"),
169 Self::Proc(error) => write!(f, "ProcError: {error}"),
170 Self::Regex(error) => write!(f, "RegexError: {error}"),
171 Self::Utf8(error) => write!(f, "Utf8Error: {error}"),
172 #[cfg(feature = "oci")]
173 Self::CgSetup(error) => write!(f, "CgroupSetupError: {error}"),
174 #[cfg(feature = "oci")]
175 Self::CgMisc(error) => write!(f, "AnyManagerError: {error}"),
176 #[cfg(feature = "oci")]
177 Self::Cont(error) => write!(f, "ContainerError: {error}"),
178 #[cfg(feature = "oci")]
179 Self::Pext(error) => write!(f, "PathBufExtError: {error}"),
180 #[cfg(feature = "oci")]
181 Self::SetTracing(error) => write!(f, "SetGlobalDefaultError: {error}"),
182 #[cfg(feature = "oci")]
183 Self::Signal(error) => write!(f, "SignalError: {error}"),
184 #[cfg(feature = "oci")]
185 Self::Spec(error) => write!(f, "OciSpecError: {error}"),
186 }
187 }
188}
189
190impl std::error::Error for SydError {
191 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
192 match self {
193 Self::Addr(error) => Some(error),
194 Self::Args(error) => Some(error),
195 Self::Nix(errno) => Some(errno),
196 Self::ParseInt(error) => Some(error),
197 Self::TryInt(error) => Some(error),
198 Self::TrySlice(error) => Some(error),
199 Self::ParseSize(_error) => None,
202 Self::Proc(error) => Some(error),
203 Self::Regex(error) => Some(error),
204 Self::Utf8(error) => Some(error),
205 #[cfg(feature = "oci")]
206 Self::CgSetup(error) => Some(error),
207 #[cfg(feature = "oci")]
208 Self::CgMisc(error) => Some(error),
209 #[cfg(feature = "oci")]
210 Self::Cont(error) => Some(error),
211 #[cfg(feature = "oci")]
212 Self::Pext(error) => Some(error),
213 #[cfg(feature = "oci")]
214 Self::SetTracing(error) => Some(error),
215 #[cfg(feature = "oci")]
216 Self::Signal(error) => Some(error),
217 #[cfg(feature = "oci")]
218 Self::Spec(error) => Some(error),
219 _ => None,
220 }
221 }
222}
223
224impl From<io::Error> for SydError {
226 fn from(err: io::Error) -> SydError {
227 SydError::Nix(err2no(&err))
228 }
229}
230
231impl From<AddrParseError> for SydError {
233 fn from(err: AddrParseError) -> SydError {
234 SydError::Addr(err)
235 }
236}
237
238impl From<Utf8Error> for SydError {
240 fn from(err: Utf8Error) -> SydError {
241 Self::Utf8(err)
242 }
243}
244
245impl From<ProcError> for SydError {
247 fn from(err: ProcError) -> SydError {
248 Self::Proc(err)
249 }
250}
251
252impl From<regex::Error> for SydError {
254 fn from(err: regex::Error) -> SydError {
255 Self::Regex(err)
256 }
257}
258
259impl From<lexopt::Error> for SydError {
261 fn from(err: lexopt::Error) -> SydError {
262 Self::Args(err)
263 }
264}
265
266impl From<CapsError> for SydError {
268 fn from(err: CapsError) -> SydError {
269 Self::Caps(err)
270 }
271}
272
273impl From<ElfError> for SydError {
275 fn from(err: ElfError) -> SydError {
276 Self::Elf(err)
277 }
278}
279
280impl From<LookupError<VarError>> for SydError {
282 fn from(err: LookupError<VarError>) -> SydError {
283 Self::Env(err)
284 }
285}
286
287impl From<Errno> for SydError {
289 fn from(err: Errno) -> SydError {
290 Self::Nix(err)
291 }
292}
293
294impl From<serde_json::Error> for SydError {
296 fn from(err: serde_json::Error) -> SydError {
297 Self::Json(err)
298 }
299}
300
301#[cfg(feature = "oci")]
303impl From<AnyManagerError> for SydError {
304 fn from(err: AnyManagerError) -> SydError {
305 Self::CgMisc(err)
306 }
307}
308
309#[cfg(feature = "oci")]
311impl From<CreateCgroupSetupError> for SydError {
312 fn from(err: CreateCgroupSetupError) -> SydError {
313 Self::CgSetup(err)
314 }
315}
316
317#[cfg(feature = "oci")]
319impl From<LibcontainerError> for SydError {
320 fn from(err: LibcontainerError) -> SydError {
321 Self::Cont(err)
322 }
323}
324
325#[cfg(feature = "oci")]
327impl From<PathBufExtError> for SydError {
328 fn from(err: PathBufExtError) -> SydError {
329 Self::Pext(err)
330 }
331}
332
333#[cfg(feature = "oci")]
335impl From<SetGlobalDefaultError> for SydError {
336 fn from(err: SetGlobalDefaultError) -> SydError {
337 Self::SetTracing(err)
338 }
339}
340
341#[cfg(feature = "oci")]
343impl From<SignalError<String>> for SydError {
344 fn from(err: SignalError<String>) -> SydError {
345 Self::Signal(err)
346 }
347}
348
349#[cfg(feature = "oci")]
351impl From<oci_spec::OciSpecError> for SydError {
352 fn from(err: oci_spec::OciSpecError) -> SydError {
353 Self::Spec(err)
354 }
355}
356
357impl From<ParseIntError> for SydError {
359 fn from(err: ParseIntError) -> SydError {
360 Self::ParseInt(err)
361 }
362}
363
364impl From<TryFromIntError> for SydError {
366 fn from(err: TryFromIntError) -> SydError {
367 Self::TryInt(err)
368 }
369}
370
371impl From<TryFromSliceError> for SydError {
373 fn from(err: TryFromSliceError) -> SydError {
374 Self::TrySlice(err)
375 }
376}
377
378impl From<parse_size::Error> for SydError {
380 fn from(err: parse_size::Error) -> SydError {
381 Self::ParseSize(err)
382 }
383}
384
385impl From<SeccompError> for SydError {
387 fn from(err: SeccompError) -> SydError {
388 Self::Scmp(err)
389 }
390}
391
392#[inline(always)]
394pub fn err2no(err: &std::io::Error) -> Errno {
395 err.raw_os_error()
396 .map(Errno::from_raw)
397 .unwrap_or(Errno::ENOSYS)
398}
399
400#[inline(always)]
402pub fn err2no_ref(err: &std::io::Error) -> Errno {
403 err.raw_os_error()
404 .map(Errno::from_raw)
405 .unwrap_or(Errno::ENOSYS)
406}
407
408#[inline(always)]
410pub fn proc_error_to_errno(error: &ProcError) -> Option<Errno> {
411 match error {
412 ProcError::PermissionDenied(_) => Some(Errno::EACCES),
413 ProcError::NotFound(_) => Some(Errno::ESRCH),
414 ProcError::Io(error, _) => Some(err2no_ref(error)),
415 ProcError::Other(_) => None,
416 ProcError::Incomplete(_) => None,
417 ProcError::InternalError(_) => None,
418 }
419}