xvc_pipeline/
error.rs

1//! Error and Result types for the pipelines crate
2use log::{debug, error, info, trace, warn};
3
4use rusqlite::Error as SqliteError;
5use std::ffi::OsString;
6use std::fmt::Debug;
7use std::io;
8use std::num::TryFromIntError;
9use std::path::PathBuf;
10use std::sync::PoisonError;
11use thiserror::Error as ThisError;
12
13#[derive(ThisError, Debug)]
14/// Error messages for pipelines crate
15#[allow(missing_docs)]
16pub enum Error {
17    #[error("Sorry. {0} is not implemented yet")]
18    Todo(&'static str),
19
20    #[error("General Xvc Pipelines Error: {source}")]
21    AnyhowError {
22        #[from]
23        source: anyhow::Error,
24    },
25
26    #[error("Xvc ECS Error: {source}")]
27    EcsError {
28        #[from]
29        source: xvc_core::XvcEcsError,
30    },
31
32    #[error("Xvc Core Error: {source}")]
33    CoreError {
34        #[from]
35        source: xvc_core::error::Error,
36    },
37
38    #[error("Xvc Config Error: {source}")]
39    ConfigError {
40        #[from]
41        source: xvc_core::XvcConfigError,
42    },
43
44    #[error("Walker Error: {source}")]
45    WalkerError {
46        #[from]
47        source: xvc_core::XvcWalkerError,
48    },
49
50    #[error("Cannot infer format from file extension: {extension:?}")]
51    CannotInferFormatFromExtension { extension: OsString },
52    #[error("Format specification for input (stdin) required.")]
53    FormatSpecificationRequired,
54    #[error("Process Error - stdout: {stdout}\nstderr: {stderr}")]
55    ProcessError { stdout: String, stderr: String },
56    #[error("Process Exec Error: {source}")]
57    ProcessExecError {
58        #[from]
59        source: subprocess::PopenError,
60    },
61    #[error("Invalid regular expression: {regex}")]
62    InvalidRegexFormat { regex: String },
63    //
64    #[error("Invalid lines definition: {line}")]
65    InvalidLinesFormat { line: String },
66    //
67    #[error("Step {step} not found in pipeline")]
68    StepNotFoundInPipeline { step: String },
69    #[error("[E1004] Json Serialization Error: {source}")]
70    JsonError {
71        #[from]
72        source: serde_json::Error,
73    },
74    #[error("Encountered NULL value in JSON map")]
75    JsonNullValueForKey { key: String },
76    //
77    #[error("TOML Serialization Error: {source}")]
78    TomlSerializationError {
79        #[from]
80        source: toml::ser::Error,
81    },
82
83    #[error("TOML Deserialization Error: {source}")]
84    TomlDeserializationError {
85        #[from]
86        source: toml::de::Error,
87    },
88
89    #[error("Yaml Error: {source}")]
90    YamlError {
91        #[from]
92        source: serde_yaml::Error,
93    },
94    #[error("Encountered NULL value in YAML map")]
95    YamlNullValueForKey { key: String },
96    #[error("[E2001] Step with name '{step_name}' already found in {pipeline_name}")]
97    StepAlreadyFoundInPipeline {
98        step_name: String,
99        pipeline_name: String,
100    },
101    #[error("[E2002] Stage with name already found")]
102    StepRequiresName,
103    #[error("[E2003] The command xvc {command} requires subcommand.")]
104    RequiresSubCommand { command: String },
105    #[error("[E2004] Requires xvc repository.")]
106    RequiresXvcRepository,
107    #[error("Pipeline {name} already found")]
108    PipelineAlreadyFound { name: String },
109    #[error("Pipeline {name} is not found")]
110    NoPipelinesFound { name: String },
111    #[error("Pipeline Steps Contain Cycle")]
112    PipelineStepsContainCycle { pipeline: String, step: String },
113    #[error("Cannot delete last pipeline")]
114    CannotDeleteLastPipeline,
115    #[error("Cannot delete default pipeline: {name}")]
116    CannotDeleteDefaultPipeline { name: String },
117    //
118    #[error("Pipeline cannot depend to itself")]
119    PipelineCannotDependToItself,
120
121    #[error("Step cannot depend to itself")]
122    StepCannotDependToItself,
123
124    #[error("Internal Error: Content Digest for Pipeline Dependencies is not available. ")]
125    NoContentDigestForPipelines,
126
127    #[error("Internal Error: Content Digest for Step Dependencies is not available. ")]
128    NoContentDigestForSteps,
129    //
130    #[error("I/O Error: {source}")]
131    IoError {
132        #[from]
133        source: io::Error,
134    },
135
136    #[error("Unicode/UTF-8 Error: {source:?}")]
137    UnicodeError {
138        #[from]
139        source: std::string::FromUtf8Error,
140    },
141    #[error("Poison Error: {cause:?}")]
142    PoisonError { cause: String },
143    #[error("Path not found: {path:?}")]
144    PathNotFound { path: OsString },
145    #[error("Path has no modification time: {path:?}")]
146    PathHasNoModificationTime { path: OsString },
147    #[error("Internal Error: XvcDependencyComparisonError in Pipelines")]
148    XvcDependencyComparisonError,
149    #[error("Missing value for key: {key}")]
150    KeyNotFound { key: String },
151    //
152    #[error("Missing value for key: {key} in {path}")]
153    KeyNotFoundInDocument { key: String, path: PathBuf },
154
155    #[error("Pattern Error: {source}")]
156    PatternError {
157        #[from]
158        source: glob::PatternError,
159    },
160
161    #[error("URL Request Error: {source}")]
162    UrlRequestError {
163        #[from]
164        source: reqwest::Error,
165    },
166
167    #[error("Invalid Parameter Format: {param} ")]
168    InvalidParameterFormat { param: String },
169
170    #[error("Unsupported param file format: {path:?} ")]
171    UnsupportedParamFileFormat { path: OsString },
172
173    #[error("Crossbeam Send Error for Type: {t:?} {cause:?}")]
174    CrossbeamSendError { t: String, cause: String },
175    #[error("Crossbeam Recv Error: {source}")]
176    CrossbeamRecvError {
177        #[from]
178        source: crossbeam_channel::RecvError,
179    },
180
181    #[error("Cannot find Pipeline: {name}")]
182    CannotFindPipeline { name: String },
183
184    #[error("Cannot parse url: {source}")]
185    CannotParseUrl {
186        #[from]
187        source: url::ParseError,
188    },
189
190    #[error("Try Receive Error: {source}")]
191    TryReceiveError {
192        #[from]
193        source: crossbeam_channel::TryRecvError,
194    },
195
196    #[error("Cannot cast from: {source}")]
197    TryFromIntError {
198        #[from]
199        source: TryFromIntError,
200    },
201
202    #[error("Sqlite Error:")]
203    SqliteError {
204        #[from]
205        source: SqliteError,
206    },
207}
208
209impl<T> From<crossbeam_channel::SendError<T>> for Error
210where
211    T: Debug,
212{
213    fn from(e: crossbeam_channel::SendError<T>) -> Self {
214        Error::CrossbeamSendError {
215            t: format!("{:#?}", e.0),
216            cause: e.to_string(),
217        }
218    }
219}
220
221impl<T: Debug> From<PoisonError<T>> for Error {
222    fn from(e: PoisonError<T>) -> Self {
223        Error::PoisonError {
224            cause: e.to_string(),
225        }
226    }
227}
228
229impl<T: Debug> From<&PoisonError<T>> for Error {
230    fn from(e: &PoisonError<T>) -> Self {
231        Error::PoisonError {
232            cause: e.to_string(),
233        }
234    }
235}
236impl Error {
237    /// Log the error and return it
238    pub fn debug(self) -> Self {
239        debug!("{}", self);
240        self
241    }
242    /// Log the error and return it
243    pub fn trace(self) -> Self {
244        trace!("{}", self);
245        self
246    }
247    /// Log the error and return it
248    pub fn warn(self) -> Self {
249        warn!("{}", self);
250        self
251    }
252    /// Log the error and return it
253    pub fn error(self) -> Self {
254        error!("{}", self);
255        self
256    }
257    /// Log the error and return it
258    pub fn info(self) -> Self {
259        info!("{}", self);
260        self
261    }
262    /// Panic with the error
263    pub fn panic(self) -> Self {
264        panic!("{}", self);
265    }
266}
267
268/// The result type for xvc pipeline crate
269pub type Result<T> = std::result::Result<T, Error>;