#[cfg(feature = "file-changes")]
use std::path::PathBuf;
use chrono::{DateTime, Utc};
use thiserror::Error;
use crate::client::MAX_RETRIES;
#[derive(Debug, thiserror::Error)]
#[cfg(feature = "file-changes")]
#[cfg_attr(docsrs, doc(cfg(feature = "file-changes")))]
pub enum DiffError {
#[error("Failed to compile regex pattern: {0}")]
RegExCompileFailed(#[from] regex::Error),
}
#[derive(Debug, thiserror::Error, PartialEq, Eq)]
pub enum OutputVariableError {
#[error("The output variable's name is empty")]
NameIsEmpty,
#[error("The output variable's name starts with a number: '{0}'")]
NameStartsWithNumber(String),
#[error("The output variable's name contains non-printable characters: '{0}'")]
NameContainsNonPrintableCharacters(String),
#[error("The output variable's value contains non-printable characters: '{0}'")]
ValueContainsNonPrintableCharacters(String),
#[error("Unsupported CI platform")]
UnsupportedPlatform,
}
#[derive(Debug, Error)]
pub enum RestClientError {
#[error(transparent)]
#[cfg(feature = "file-changes")]
#[cfg_attr(docsrs, doc(cfg(feature = "file-changes")))]
DiffError(#[from] DiffError),
#[error("Encountered malformed event info: {0}")]
MalformedEventInfo(String),
#[error(transparent)]
Request(#[from] reqwest::Error),
#[error("Failed to {task}: {source}")]
RequestContext {
task: String,
#[source]
source: reqwest::Error,
},
#[error("Failed to {task}: {source}")]
Io {
task: String,
#[source]
source: std::io::Error,
},
#[error("Git command error: {0}")]
#[cfg(feature = "file-changes")]
#[cfg_attr(docsrs, doc(cfg(feature = "file-changes")))]
GitCommand(String),
#[error("Primary Rate Limit exceeded (no reset time provided)")]
RateLimitNoReset,
#[error("Primary Rate Limit exceeded; resets at {0}")]
RateLimitPrimary(DateTime<Utc>),
#[error("Rate Limit exceeded after all {MAX_RETRIES} retries exhausted")]
RateLimitSecondary,
#[error("Failed to clone request object for auto-retries")]
CannotCloneRequest,
#[error("Tried to create a header value from invalid string data")]
InvalidHeaderValue(#[from] reqwest::header::InvalidHeaderValue),
#[error("Failed to convert header value to string")]
UnexpectedHeaderValue(#[from] reqwest::header::ToStrError),
#[error("Failed to parse integer from header value: {0}")]
HeaderParseInt(#[from] std::num::ParseIntError),
#[error("Failed to parse URL:{0}")]
UrlParse(#[from] url::ParseError),
#[error("Failed to {task}: {source}")]
Json {
task: String,
#[source]
source: serde_json::Error,
},
#[error("Failed to get env var '{name}': {source}")]
EnvVar {
name: String,
#[source]
source: std::env::VarError,
},
#[error("OutputVariable is malformed: {0}")]
OutputVar(#[from] OutputVariableError),
}
impl RestClientError {
pub fn env_var(name: &str, source: std::env::VarError) -> Self {
Self::EnvVar {
name: name.to_string(),
source,
}
}
pub fn io(task: &str, source: std::io::Error) -> Self {
Self::Io {
task: task.to_string(),
source,
}
}
pub fn add_request_context(self, task: &str) -> Self {
match self {
Self::Request(e) => Self::RequestContext {
task: task.to_string(),
source: e,
},
_ => self,
}
}
pub fn json(task: &str, source: serde_json::Error) -> Self {
Self::Json {
task: task.to_string(),
source,
}
}
}
#[cfg(feature = "file-changes")]
#[derive(Debug, Error)]
#[cfg_attr(docsrs, doc(cfg(feature = "file-changes")))]
pub enum DirWalkError {
#[error("Failed to read {path}: {source}")]
ReadDir {
path: PathBuf,
#[source]
source: std::io::Error,
},
#[error(transparent)]
OsError(#[from] std::io::Error),
}
#[cfg(test)]
mod tests {
use super::RestClientError;
#[test]
fn no_added_req_ctx() {
let err = RestClientError::CannotCloneRequest;
assert!(matches!(
err.add_request_context("some task"),
RestClientError::CannotCloneRequest
));
}
}