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, PartialEq, Eq)]
12pub enum OutputVariableError {
13 #[error("The output variable's name is empty")]
15 NameIsEmpty,
16 #[error("The output variable's name starts with a number: '{0}'")]
18 NameStartsWithNumber(String),
19 #[error("The output variable's name contains non-printable characters: '{0}'")]
21 NameContainsNonPrintableCharacters(String),
22 #[error("The output variable's value contains non-printable characters: '{0}'")]
24 ValueContainsNonPrintableCharacters(String),
25 #[error("Unsupported CI platform")]
27 UnsupportedPlatform,
28}
29
30#[derive(Debug, Error)]
32pub enum RestClientError {
33 #[error(transparent)]
35 Request(#[from] reqwest::Error),
36
37 #[error("Failed to {task}: {source}")]
39 RequestContext {
40 task: String,
41 #[source]
42 source: reqwest::Error,
43 },
44
45 #[error("Failed to {task}: {source}")]
47 Io {
48 task: String,
49 #[source]
50 source: std::io::Error,
51 },
52
53 #[error("Git command error: {0}")]
55 #[cfg(feature = "file-changes")]
56 #[cfg_attr(docsrs, doc(cfg(feature = "file-changes")))]
57 GitCommand(String),
58
59 #[error("Primary Rate Limit exceeded (no reset time provided)")]
62 RateLimitNoReset,
63
64 #[error("Primary Rate Limit exceeded; resets at {0}")]
66 RateLimitPrimary(DateTime<Utc>),
67
68 #[error("Rate Limit exceeded after all {MAX_RETRIES} retries exhausted")]
70 RateLimitSecondary,
71
72 #[error("Failed to clone request object for auto-retries")]
74 CannotCloneRequest,
75
76 #[error("Tried to create a header value from invalid string data")]
78 InvalidHeaderValue(#[from] reqwest::header::InvalidHeaderValue),
79
80 #[error("Failed to convert header value to string")]
82 UnexpectedHeaderValue(#[from] reqwest::header::ToStrError),
83
84 #[error("Failed to parse integer from header value: {0}")]
86 HeaderParseInt(#[from] std::num::ParseIntError),
87
88 #[error("Failed to parse URL:{0}")]
90 UrlParse(#[from] url::ParseError),
91
92 #[error("Failed to {task}: {source}")]
94 Json {
95 task: String,
96 #[source]
97 source: serde_json::Error,
98 },
99
100 #[error("Failed to get env var '{name}': {source}")]
102 EnvVar {
103 name: String,
104 #[source]
105 source: std::env::VarError,
106 },
107
108 #[error("OutputVariable is malformed: {0}")]
110 OutputVar(#[from] OutputVariableError),
111}
112
113impl RestClientError {
114 pub fn env_var(name: &str, source: std::env::VarError) -> Self {
116 Self::EnvVar {
117 name: name.to_string(),
118 source,
119 }
120 }
121
122 pub fn io(task: &str, source: std::io::Error) -> Self {
124 Self::Io {
125 task: task.to_string(),
126 source,
127 }
128 }
129
130 pub fn add_request_context(self, task: &str) -> Self {
135 match self {
136 Self::Request(e) => Self::RequestContext {
137 task: task.to_string(),
138 source: e,
139 },
140 _ => self,
141 }
142 }
143
144 pub fn json(task: &str, source: serde_json::Error) -> Self {
146 Self::Json {
147 task: task.to_string(),
148 source,
149 }
150 }
151}
152
153#[cfg(feature = "file-changes")]
158#[derive(Debug, Error)]
159#[cfg_attr(docsrs, doc(cfg(feature = "file-changes")))]
160pub enum DirWalkError {
161 #[error("Failed to read {path}: {source}")]
162 ReadDir {
163 path: PathBuf,
164 #[source]
165 source: std::io::Error,
166 },
167
168 #[error(transparent)]
169 OsError(#[from] std::io::Error),
170}
171
172#[cfg(test)]
173mod tests {
174 use super::RestClientError;
175
176 #[test]
177 fn no_added_req_ctx() {
178 let err = RestClientError::CannotCloneRequest;
179 assert!(matches!(
180 err.add_request_context("some task"),
181 RestClientError::CannotCloneRequest
182 ));
183 }
184}