80f9e01
use std::fmt;
#[derive(Debug)]
pub enum ImportError {
Disabled,
Canceled,
BadRequest(String),
Unauthorized,
Forbidden,
NotFound,
Conflict(String),
RateLimited(String),
Upstream(String),
Internal(String),
}
impl ImportError {
#[must_use]
pub fn is_permanent(&self) -> bool {
matches!(
self,
Self::Disabled
| Self::Canceled
| Self::BadRequest(_)
| Self::Unauthorized
| Self::Forbidden
| Self::NotFound
| Self::Conflict(_)
)
}
}
impl fmt::Display for ImportError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Disabled => write!(f, "import is disabled"),
Self::Canceled => write!(f, "import canceled"),
Self::BadRequest(message) => write!(f, "{message}"),
Self::Unauthorized => write!(f, "unauthorized"),
Self::Forbidden => write!(f, "forbidden"),
Self::NotFound => write!(f, "not found"),
Self::Conflict(message) => write!(f, "{message}"),
Self::RateLimited(message) => write!(f, "{message}"),
Self::Upstream(message) => write!(f, "{message}"),
Self::Internal(message) => write!(f, "{message}"),
}
}
}
impl std::error::Error for ImportError {}
export::db_error_conversions!(ImportError);
export::export_error_conversion!(ImportError);
export::json_payload_conversion!(ImportError);
impl From<git::share::errors::GitError> for ImportError {
fn from(error: git::share::errors::GitError) -> Self {
use git::share::errors::GitError as G;
match error {
G::InvalidArgument(msg) => Self::BadRequest(msg),
G::NotFound => Self::NotFound,
G::Unauthorized => Self::Unauthorized,
G::Forbidden => Self::Forbidden,
G::Conflict(msg) => Self::Conflict(msg),
G::Cache(_) | G::Git(_) | G::Internal(_) => Self::Internal(error.to_string()),
}
}
}
impl From<reqwest::Error> for ImportError {
fn from(error: reqwest::Error) -> Self {
Self::Upstream(format!("source forge request failed: {error}"))
}
}
export::api_error! {
log: "import",
pub enum ApiError {
BadRequest(400, "request failed validation"),
Unauthorized(401, "authentication required"),
Forbidden(403, "operation not allowed"),
NotFound(404, "resource not found"),
Conflict(409, "resource conflict"),
TooManyRequests(429, "rate limit exceeded"),
Internal(500, "internal server error"),
BadGateway(502, "upstream forge request failed"),
ServiceUnavailable(503, "import is unavailable"),
}
}
impl From<ImportError> for ApiError {
fn from(error: ImportError) -> Self {
match error {
ImportError::Disabled => Self::build(
503,
export::rest::AppResponseData::err(503, "import is unavailable")
.with_error_code("import_disabled"),
),
ImportError::Canceled => Self::bad_request("import job canceled"),
ImportError::BadRequest(msg) => Self::bad_request(msg),
ImportError::Unauthorized => Self::unauthorized(),
ImportError::Forbidden => Self::forbidden(),
ImportError::NotFound => Self::not_found("import job or source not found"),
ImportError::Conflict(msg) => Self::conflict(msg),
ImportError::RateLimited(msg) => Self::rate_limited(msg),
ImportError::Upstream(msg) => Self::build(
502,
export::rest::AppResponseData::err(502, "upstream forge request failed")
.with_error(msg)
.with_error_code("import_upstream_failed"),
),
ImportError::Internal(message) => Self::internal(message),
}
}
}