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", "git2",
"reqwest", "reqwest",
"serde", "serde",
"serde_json",
"soft_assert", "soft_assert",
"thiserror", "thiserror",
"time", "time",

View file

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

View file

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

View file

@ -17,6 +17,11 @@ async fn ci() -> eyre::Result<()> {
errors += 1; errors += 1;
for (i, err) in report.chain().enumerate() { for (i, err) in report.chain().enumerate() {
println!("{i}. {err}"); 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 { if errors > 0 {