nmstate/
error.rs

1// SPDX-License-Identifier: Apache-2.0
2
3use std::error::Error;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6#[non_exhaustive]
7#[allow(dead_code)]
8#[derive(Default)]
9pub enum ErrorKind {
10    InvalidArgument,
11    PluginFailure,
12    #[default]
13    Bug,
14    VerificationError,
15    NotImplementedError,
16    NotSupportedError,
17    KernelIntegerRoundedError,
18    DependencyError,
19    PolicyError,
20    PermissionError,
21    SrIovVfNotFound,
22}
23
24#[cfg(feature = "query_apply")]
25impl ErrorKind {
26    pub(crate) fn can_retry(&self) -> bool {
27        matches!(
28            self,
29            ErrorKind::PluginFailure
30                | ErrorKind::Bug
31                | ErrorKind::VerificationError
32                | ErrorKind::SrIovVfNotFound
33        )
34    }
35
36    // Indicate this error can be ignore at the final retry. This group of
37    // errors is only used for verification retry. For example waiting
38    // SR-IOV configure all the VFs
39    pub(crate) fn can_ignore(&self) -> bool {
40        matches!(self, ErrorKind::SrIovVfNotFound)
41    }
42}
43
44impl std::fmt::Display for ErrorKind {
45    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46        write!(f, "{self:?}")
47    }
48}
49
50impl std::fmt::Display for NmstateError {
51    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52        if self.kind == ErrorKind::PolicyError {
53            write!(
54                f,
55                "{}: {}\n| {}\n| {:.<4$}^",
56                self.kind, self.msg, self.line, "", self.position
57            )
58        } else {
59            write!(f, "{}: {}", self.kind, self.msg)
60        }
61    }
62}
63
64impl Error for NmstateError {}
65
66#[derive(Debug, Default, Clone, PartialEq, Eq)]
67#[non_exhaustive]
68pub struct NmstateError {
69    kind: ErrorKind,
70    msg: String,
71    line: String,
72    position: usize,
73}
74
75impl NmstateError {
76    pub fn new(kind: ErrorKind, msg: String) -> Self {
77        Self {
78            kind,
79            msg,
80            ..Default::default()
81        }
82    }
83
84    pub fn new_policy_error(msg: String, line: &str, position: usize) -> Self {
85        Self {
86            kind: ErrorKind::PolicyError,
87            line: line.to_string(),
88            msg,
89            position,
90        }
91    }
92
93    pub fn kind(&self) -> ErrorKind {
94        self.kind
95    }
96
97    pub fn msg(&self) -> &str {
98        self.msg.as_str()
99    }
100
101    pub fn line(&self) -> &str {
102        self.line.as_str()
103    }
104
105    /// The position of character in line which cause the PolicyError, the
106    /// first character is position 0.
107    pub fn position(&self) -> usize {
108        self.position
109    }
110}
111
112impl From<serde_json::Error> for NmstateError {
113    fn from(e: serde_json::Error) -> Self {
114        NmstateError::new(
115            ErrorKind::InvalidArgument,
116            format!("Invalid property : {e}"),
117        )
118    }
119}
120
121impl From<std::net::AddrParseError> for NmstateError {
122    fn from(e: std::net::AddrParseError) -> Self {
123        NmstateError::new(
124            ErrorKind::InvalidArgument,
125            format!("Invalid IP address : {e}"),
126        )
127    }
128}