cgroups_rs/fs/
error.rs

1// Copyright (c) 2018 Levente Kurusa
2// Copyright (c) 2020 Ant Group
3//
4// SPDX-License-Identifier: Apache-2.0 or MIT
5//
6
7use std::error::Error as StdError;
8use std::fmt;
9
10/// The different types of errors that can occur while manipulating control groups.
11#[derive(thiserror::Error, Debug, Eq, PartialEq)]
12pub enum ErrorKind {
13    #[error("fs error")]
14    FsError,
15
16    #[error("common error: {0}")]
17    Common(String),
18
19    /// An error occured while writing to a control group file.
20    #[error("unable to write to a control group file {0}, value {1}")]
21    WriteFailed(String, String),
22
23    /// An error occured while trying to read from a control group file.
24    #[error("unable to read a control group file {0}")]
25    ReadFailed(String),
26
27    /// An error occured while trying to remove a control group.
28    #[error("unable to remove a control group")]
29    RemoveFailed,
30
31    /// An error occured while trying to parse a value from a control group file.
32    ///
33    /// In the future, there will be some information attached to this field.
34    #[error("unable to parse control group file")]
35    ParseError,
36
37    /// You tried to do something invalid.
38    ///
39    /// This could be because you tried to set a value in a control group that is not a root
40    /// control group. Or, when using unified hierarchy, you tried to add a task in a leaf node.
41    #[error("the requested operation is invalid")]
42    InvalidOperation,
43
44    /// The path of the control group was invalid.
45    ///
46    /// This could be caused by trying to escape the control group filesystem via a string of "..".
47    /// This crate checks against this and operations will fail with this error.
48    #[error("the given path is invalid")]
49    InvalidPath,
50
51    #[error("invalid bytes size")]
52    InvalidBytesSize,
53
54    /// The specified controller is not in the list of supported controllers.
55    #[error("specified controller is not in the list of supported controllers")]
56    SpecifiedControllers,
57
58    /// Using method in wrong cgroup version.
59    #[error("using method in wrong cgroup version")]
60    CgroupVersion,
61
62    /// Using method in wrong cgroup mode.
63    #[error("using method in wrong cgroup mode.")]
64    CgroupMode,
65
66    /// Subsystems is empty.
67    #[error("subsystems is empty")]
68    SubsystemsEmpty,
69
70    /// An unknown error has occured.
71    #[error("an unknown error")]
72    Other,
73}
74
75#[derive(Debug)]
76pub struct Error {
77    kind: ErrorKind,
78    cause: Option<Box<dyn StdError + Send + Sync>>,
79}
80
81impl fmt::Display for Error {
82    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
83        if let Some(cause) = &self.cause {
84            write!(f, "{} caused by: {:?}", &self.kind, cause)
85        } else {
86            write!(f, "{}", &self.kind)
87        }
88    }
89}
90
91impl StdError for Error {
92    fn source(&self) -> Option<&(dyn StdError + 'static)> {
93        #[allow(clippy::manual_map)]
94        match self.cause {
95            Some(ref x) => Some(&**x),
96            None => None,
97        }
98    }
99}
100
101impl Error {
102    pub(crate) fn from_string(s: String) -> Self {
103        Self {
104            kind: ErrorKind::Common(s),
105            cause: None,
106        }
107    }
108    pub(crate) fn new(kind: ErrorKind) -> Self {
109        Self { kind, cause: None }
110    }
111
112    pub(crate) fn with_cause<E>(kind: ErrorKind, cause: E) -> Self
113    where
114        E: 'static + Send + Sync + StdError,
115    {
116        Self {
117            kind,
118            cause: Some(Box::new(cause)),
119        }
120    }
121
122    pub fn kind(&self) -> &ErrorKind {
123        &self.kind
124    }
125}
126
127pub type Result<T> = ::std::result::Result<T, Error>;