scouter_types/
error.rs

1use pyo3::exceptions::PyRuntimeError;
2use pyo3::PyErr;
3use thiserror::Error;
4
5#[derive(Error, Debug)]
6pub enum UtilError {
7    #[error("Failed to get parent path")]
8    GetParentPathError,
9
10    #[error("Failed to create directory")]
11    CreateDirectoryError,
12
13    #[error("Failed to read to create path")]
14    CreatePathError,
15
16    #[error(transparent)]
17    IoError(#[from] std::io::Error),
18
19    #[error(transparent)]
20    SerdeJsonError(#[from] serde_json::Error),
21}
22
23impl From<UtilError> for PyErr {
24    fn from(err: UtilError) -> PyErr {
25        let msg = err.to_string();
26        PyRuntimeError::new_err(msg)
27    }
28}
29
30#[derive(Error, Debug)]
31pub enum TypeError {
32    #[error("Start time must be before end time")]
33    StartTimeError,
34
35    #[error("Invalid schedule")]
36    InvalidScheduleError,
37
38    #[error("Missing space argument")]
39    MissingSpaceError,
40
41    #[error("Missing name argument")]
42    MissingNameError,
43
44    #[error("Missing version argument")]
45    MissingVersionError,
46
47    #[error("Missing alert_config argument")]
48    MissingAlertConfigError,
49
50    #[error("No metrics found")]
51    NoMetricsError,
52
53    #[error(transparent)]
54    SerdeJsonError(#[from] serde_json::Error),
55
56    #[error("Invalid number")]
57    InvalidNumberError,
58
59    #[error("Root must be an object")]
60    RootMustBeObject,
61
62    #[error("Unsupported type: {0}")]
63    UnsupportedTypeError(String),
64
65    #[error("Failed to downcast Python object: {0}")]
66    DowncastError(String),
67
68    #[error("Invalid data type")]
69    InvalidDataType,
70
71    #[error("Missing value for string feature")]
72    MissingStringValueError,
73
74    #[error("{0}")]
75    PyError(String),
76}
77
78impl<'a> From<pyo3::DowncastError<'a, 'a>> for TypeError {
79    fn from(err: pyo3::DowncastError) -> Self {
80        TypeError::DowncastError(err.to_string())
81    }
82}
83
84impl From<TypeError> for PyErr {
85    fn from(err: TypeError) -> PyErr {
86        let msg = err.to_string();
87        PyRuntimeError::new_err(msg)
88    }
89}
90
91impl From<PyErr> for TypeError {
92    fn from(err: PyErr) -> TypeError {
93        TypeError::PyError(err.to_string())
94    }
95}
96
97#[derive(Error, Debug)]
98pub enum ContractError {
99    #[error(transparent)]
100    TypeError(#[from] TypeError),
101
102    #[error("{0}")]
103    PyError(String),
104}
105
106impl From<ContractError> for PyErr {
107    fn from(err: ContractError) -> PyErr {
108        let msg = err.to_string();
109        PyRuntimeError::new_err(msg)
110    }
111}
112
113impl From<PyErr> for ContractError {
114    fn from(err: PyErr) -> ContractError {
115        ContractError::PyError(err.to_string())
116    }
117}
118
119#[derive(Error, Debug)]
120pub enum RecordError {
121    #[error("Unable to extract record into any known ServerRecord variant")]
122    ExtractionError,
123
124    #[error("No server records found")]
125    EmptyServerRecordsError,
126
127    #[error(transparent)]
128    SerdeJsonError(#[from] serde_json::Error),
129
130    #[error("Unexpected record type")]
131    InvalidDriftTypeError,
132
133    #[error("{0}")]
134    PyError(String),
135}
136
137impl From<RecordError> for PyErr {
138    fn from(err: RecordError) -> PyErr {
139        let msg = err.to_string();
140        PyRuntimeError::new_err(msg)
141    }
142}
143
144impl From<PyErr> for RecordError {
145    fn from(err: PyErr) -> RecordError {
146        RecordError::PyError(err.to_string())
147    }
148}
149
150#[derive(Error, Debug)]
151pub enum ProfileError {
152    #[error(transparent)]
153    SerdeJsonError(#[from] serde_json::Error),
154
155    #[error("Features and array are not the same length")]
156    FeatureArrayLengthError,
157
158    #[error("Unexpected record type")]
159    InvalidDriftTypeError,
160
161    #[error(transparent)]
162    UtilError(#[from] UtilError),
163
164    #[error(transparent)]
165    TypeError(#[from] TypeError),
166
167    #[error(transparent)]
168    IoError(#[from] std::io::Error),
169
170    #[error("Missing sample argument")]
171    MissingSampleError,
172
173    #[error("Missing sample size argument")]
174    MissingSampleSizeError,
175
176    #[error("Custom alert thresholds have not been set")]
177    CustomThresholdNotSetError,
178
179    #[error("Custom alert threshold not found")]
180    CustomAlertThresholdNotFound,
181
182    #[error("{0}")]
183    PyError(String),
184}
185
186impl From<ProfileError> for PyErr {
187    fn from(err: ProfileError) -> PyErr {
188        let msg = err.to_string();
189        PyRuntimeError::new_err(msg)
190    }
191}
192
193impl From<PyErr> for ProfileError {
194    fn from(err: PyErr) -> ProfileError {
195        ProfileError::PyError(err.to_string())
196    }
197}