1use 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#[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 #[error("Invalid lines definition: {line}")]
65 InvalidLinesFormat { line: String },
66 #[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 #[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 #[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 #[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 #[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 pub fn debug(self) -> Self {
239 debug!("{}", self);
240 self
241 }
242 pub fn trace(self) -> Self {
244 trace!("{}", self);
245 self
246 }
247 pub fn warn(self) -> Self {
249 warn!("{}", self);
250 self
251 }
252 pub fn error(self) -> Self {
254 error!("{}", self);
255 self
256 }
257 pub fn info(self) -> Self {
259 info!("{}", self);
260 self
261 }
262 pub fn panic(self) -> Self {
264 panic!("{}", self);
265 }
266}
267
268pub type Result<T> = std::result::Result<T, Error>;