git_bot_feedback/
error.rs1#[cfg(feature = "file-changes")]
3use std::path::PathBuf;
4
5use chrono::{DateTime, Utc};
6use thiserror::Error;
7
8use crate::client::MAX_RETRIES;
9
10#[derive(Debug, thiserror::Error)]
12#[cfg(feature = "file-changes")]
13#[cfg_attr(docsrs, doc(cfg(feature = "file-changes")))]
14pub enum DiffError {
15 #[error("Failed to compile regex pattern: {0}")]
17 RegExCompileFailed(#[from] regex::Error),
18}
19
20#[derive(Debug, thiserror::Error, PartialEq, Eq)]
22pub enum OutputVariableError {
23 #[error("The output variable's name is empty")]
25 NameIsEmpty,
26 #[error("The output variable's name starts with a number: '{0}'")]
28 NameStartsWithNumber(String),
29 #[error("The output variable's name contains non-printable characters: '{0}'")]
31 NameContainsNonPrintableCharacters(String),
32 #[error("The output variable's value contains non-printable characters: '{0}'")]
34 ValueContainsNonPrintableCharacters(String),
35 #[error("Unsupported CI platform")]
37 UnsupportedPlatform,
38}
39
40#[derive(Debug, Error)]
42pub enum RestClientError {
43 #[error(transparent)]
45 #[cfg(feature = "file-changes")]
46 #[cfg_attr(docsrs, doc(cfg(feature = "file-changes")))]
47 DiffError(#[from] DiffError),
48
49 #[error("Encountered malformed event info: {0}")]
51 MalformedEventInfo(String),
52
53 #[error(transparent)]
55 Request(#[from] reqwest::Error),
56
57 #[error("Failed to {task}: {source}")]
59 RequestContext {
60 task: String,
62 #[source]
64 source: reqwest::Error,
65 },
66
67 #[error("Failed to {task}: {source}")]
69 Io {
70 task: String,
72 #[source]
74 source: std::io::Error,
75 },
76
77 #[error("Git command error: {0}")]
79 #[cfg(feature = "file-changes")]
80 #[cfg_attr(docsrs, doc(cfg(feature = "file-changes")))]
81 GitCommand(String),
82
83 #[error("Primary Rate Limit exceeded (no reset time provided)")]
86 RateLimitNoReset,
87
88 #[error("Primary Rate Limit exceeded; resets at {0}")]
90 RateLimitPrimary(DateTime<Utc>),
91
92 #[error("Rate Limit exceeded after all {MAX_RETRIES} retries exhausted")]
94 RateLimitSecondary,
95
96 #[error("Failed to clone request object for auto-retries")]
98 CannotCloneRequest,
99
100 #[error("Tried to create a header value from invalid string data")]
102 InvalidHeaderValue(#[from] reqwest::header::InvalidHeaderValue),
103
104 #[error("Failed to convert header value to string")]
106 UnexpectedHeaderValue(#[from] reqwest::header::ToStrError),
107
108 #[error("Failed to parse integer from header value: {0}")]
110 HeaderParseInt(#[from] std::num::ParseIntError),
111
112 #[error("Failed to parse URL:{0}")]
114 UrlParse(#[from] url::ParseError),
115
116 #[error("Failed to {task}: {source}")]
118 Json {
119 task: String,
121 #[source]
123 source: serde_json::Error,
124 },
125
126 #[error("Failed to get env var '{name}': {source}")]
128 EnvVar {
129 name: String,
131 #[source]
133 source: std::env::VarError,
134 },
135
136 #[error("OutputVariable is malformed: {0}")]
138 OutputVar(#[from] OutputVariableError),
139}
140
141impl RestClientError {
142 pub fn env_var(name: &str, source: std::env::VarError) -> Self {
144 Self::EnvVar {
145 name: name.to_string(),
146 source,
147 }
148 }
149
150 pub fn io(task: &str, source: std::io::Error) -> Self {
152 Self::Io {
153 task: task.to_string(),
154 source,
155 }
156 }
157
158 pub fn add_request_context(self, task: &str) -> Self {
163 match self {
164 Self::Request(e) => Self::RequestContext {
165 task: task.to_string(),
166 source: e,
167 },
168 _ => self,
169 }
170 }
171
172 pub fn json(task: &str, source: serde_json::Error) -> Self {
174 Self::Json {
175 task: task.to_string(),
176 source,
177 }
178 }
179}
180
181#[cfg(feature = "file-changes")]
186#[derive(Debug, Error)]
187#[cfg_attr(docsrs, doc(cfg(feature = "file-changes")))]
188pub enum DirWalkError {
189 #[error("Failed to read {path}: {source}")]
191 ReadDir {
192 path: PathBuf,
194 #[source]
196 source: std::io::Error,
197 },
198
199 #[error(transparent)]
201 OsError(#[from] std::io::Error),
202}
203
204#[cfg(test)]
205mod tests {
206 use super::RestClientError;
207
208 #[test]
209 fn no_added_req_ctx() {
210 let err = RestClientError::CannotCloneRequest;
211 assert!(matches!(
212 err.add_request_context("some task"),
213 RestClientError::CannotCloneRequest
214 ));
215 }
216}