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}
26
27#[derive(Debug, Error)]
29pub enum RestClientError {
30 #[error(transparent)]
32 Request(#[from] reqwest::Error),
33
34 #[error("Failed to {task}: {source}")]
36 RequestContext {
37 task: String,
38 #[source]
39 source: reqwest::Error,
40 },
41
42 #[error("Failed to {task}: {source}")]
44 Io {
45 task: String,
46 #[source]
47 source: std::io::Error,
48 },
49
50 #[error("Git command error: {0}")]
52 #[cfg(feature = "file-changes")]
53 #[cfg_attr(docsrs, doc(cfg(feature = "file-changes")))]
54 GitCommand(String),
55
56 #[error("Primary Rate Limit exceeded (no reset time provided)")]
59 RateLimitNoReset,
60
61 #[error("Primary Rate Limit exceeded; resets at {0}")]
63 RateLimitPrimary(DateTime<Utc>),
64
65 #[error("Rate Limit exceeded after all {MAX_RETRIES} retries exhausted")]
67 RateLimitSecondary,
68
69 #[error("Failed to clone request object for auto-retries")]
71 CannotCloneRequest,
72
73 #[error("Tried to create a header value from invalid string data")]
75 InvalidHeaderValue(#[from] reqwest::header::InvalidHeaderValue),
76
77 #[error("Failed to convert header value to string")]
79 UnexpectedHeaderValue(#[from] reqwest::header::ToStrError),
80
81 #[error("Failed to parse integer from header value: {0}")]
83 HeaderParseInt(#[from] std::num::ParseIntError),
84
85 #[error("Failed to parse URL:{0}")]
87 UrlParse(#[from] url::ParseError),
88
89 #[error("Failed to {task}: {source}")]
91 Json {
92 task: String,
93 #[source]
94 source: serde_json::Error,
95 },
96
97 #[error("Failed to get env var '{name}': {source}")]
99 EnvVar {
100 name: String,
101 #[source]
102 source: std::env::VarError,
103 },
104
105 #[error("OutputVariable is malformed: {0}")]
107 OutputVar(#[from] OutputVariableError),
108}
109
110impl RestClientError {
111 pub fn env_var(name: &str, source: std::env::VarError) -> Self {
113 Self::EnvVar {
114 name: name.to_string(),
115 source,
116 }
117 }
118
119 pub fn io(task: &str, source: std::io::Error) -> Self {
121 Self::Io {
122 task: task.to_string(),
123 source,
124 }
125 }
126
127 pub fn add_request_context(self, task: &str) -> Self {
132 match self {
133 Self::Request(e) => Self::RequestContext {
134 task: task.to_string(),
135 source: e,
136 },
137 _ => self,
138 }
139 }
140
141 pub fn json(task: &str, source: serde_json::Error) -> Self {
143 Self::Json {
144 task: task.to_string(),
145 source,
146 }
147 }
148}
149
150#[cfg(feature = "file-changes")]
155#[derive(Debug, Error)]
156#[cfg_attr(docsrs, doc(cfg(feature = "file-changes")))]
157pub enum DirWalkError {
158 #[error("Failed to read {path}: {source}")]
159 ReadDir {
160 path: PathBuf,
161 #[source]
162 source: std::io::Error,
163 },
164
165 #[error(transparent)]
166 OsError(#[from] std::io::Error),
167}
168
169#[cfg(test)]
170mod tests {
171 use super::RestClientError;
172
173 #[test]
174 fn no_added_req_ctx() {
175 let err = RestClientError::CannotCloneRequest;
176 assert!(matches!(
177 err.add_request_context("some task"),
178 RestClientError::CannotCloneRequest
179 ));
180 }
181}