1
0
Fork 0

include body in ForgejoError::BadStructure

This commit is contained in:
Cyborus 2023-12-10 00:53:52 -05:00
parent 31a53eb88a
commit b952e1108a
No known key found for this signature in database
4 changed files with 20 additions and 15 deletions

1
Cargo.lock generated
View file

@ -174,6 +174,7 @@ dependencies = [
"git2",
"reqwest",
"serde",
"serde_json",
"soft_assert",
"thiserror",
"time",

View file

@ -13,6 +13,7 @@ tokio = { version = "1.29.1", features = ["net"] }
url = { version = "2.4.0", features = ["serde"] }
serde = { version = "1.0.168", features = ["derive"] }
time = { version = "0.3.22", features = ["parsing", "serde", "formatting"] }
serde_json = "1.0.108"
[dev-dependencies]
eyre = "0.6.9"

View file

@ -30,28 +30,18 @@ pub enum ForgejoError {
HostRequired,
#[error("scheme must be http or https")]
HttpRequired,
#[error("{0}")] // for some reason, you can't use `source` and `transparent` together
ReqwestError(#[source] reqwest::Error),
#[error(transparent)]
ReqwestError(#[from] reqwest::Error),
#[error("API key should be ascii")]
KeyNotAscii,
#[error("the response from forgejo was not properly structured")]
BadStructure(#[source] reqwest::Error),
BadStructure(#[source] serde_json::Error, String),
#[error("unexpected status code {} {}", .0.as_u16(), .0.canonical_reason().unwrap_or(""))]
UnexpectedStatusCode(StatusCode),
#[error("{} {}: {}", .0.as_u16(), .0.canonical_reason().unwrap_or(""), .1)]
ApiError(StatusCode, String),
}
impl From<reqwest::Error> for ForgejoError {
fn from(e: reqwest::Error) -> Self {
if e.is_decode() {
ForgejoError::BadStructure(e)
} else {
ForgejoError::ReqwestError(e)
}
}
}
impl Forgejo {
pub fn new(api_key: &str, url: Url) -> Result<Self, ForgejoError> {
Self::with_user_agent(api_key, url, "forgejo-api-rs")
@ -163,7 +153,11 @@ impl Forgejo {
async fn execute<T: DeserializeOwned>(&self, request: Request) -> Result<T, ForgejoError> {
let response = self.client.execute(request).await?;
match response.status() {
status if status.is_success() => Ok(response.json::<T>().await?),
status if status.is_success() => {
let body = response.text().await?;
let out = serde_json::from_str(&body).map_err(|e| ForgejoError::BadStructure(e, body))?;
Ok(out)
},
status if status.is_client_error() => Err(ForgejoError::ApiError(
status,
response.json::<ErrorMessage>().await?.message,
@ -192,7 +186,11 @@ impl Forgejo {
) -> Result<Option<T>, ForgejoError> {
let response = self.client.execute(request).await?;
match response.status() {
status if status.is_success() => Ok(Some(response.json::<T>().await?)),
status if status.is_success() => {
let body = response.text().await?;
let out = serde_json::from_str(&body).map_err(|e| ForgejoError::BadStructure(e, body))?;
Ok(out)
},
StatusCode::NOT_FOUND => Ok(None),
status if status.is_client_error() => Err(ForgejoError::ApiError(
status,

View file

@ -17,6 +17,11 @@ async fn ci() -> eyre::Result<()> {
errors += 1;
for (i, err) in report.chain().enumerate() {
println!("{i}. {err}");
if let Some(err) = err.downcast_ref::<forgejo_api::ForgejoError>() {
if let forgejo_api::ForgejoError::BadStructure(_, body) = err {
println!("BODY: {body}");
}
}
}
}
if errors > 0 {