diff --git a/src/error.rs b/src/error.rs index 1a4e9be5..a987fdc8 100644 --- a/src/error.rs +++ b/src/error.rs @@ -97,12 +97,13 @@ pub enum Error { } /// An error returned from GitHub's API. -#[derive(serde::Deserialize, Debug, Clone)] +#[derive(Debug, Clone)] #[non_exhaustive] pub struct GitHubError { pub documentation_url: Option, pub errors: Option>, pub message: String, + pub status_code: http::StatusCode, } impl fmt::Display for GitHubError { diff --git a/src/lib.rs b/src/lib.rs index 7e55163d..229d0c48 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -211,7 +211,7 @@ use hyper::{Request, Response}; use once_cell::sync::Lazy; use secrecy::{ExposeSecret, SecretString}; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use snafu::*; use tower::{buffer::Buffer, util::BoxService, BoxError, Layer, Service, ServiceExt}; @@ -294,6 +294,13 @@ pub fn format_media_type(media_type: impl AsRef) -> String { format!("application/vnd.github.v3.{media_type}{json_suffix}") } +#[derive(Debug, Deserialize)] +struct GitHubErrorBody { + pub documentation_url: Option, + pub errors: Option>, + pub message: String, +} + /// Maps a GitHub error response into and `Err()` variant if the status is /// not a success. pub async fn map_github_error( @@ -302,12 +309,21 @@ pub async fn map_github_error( if response.status().is_success() { Ok(response) } else { - let b: error::GitHubError = - serde_json::from_slice(response.into_body().collect().await?.to_bytes().as_ref()) - .context(error::SerdeSnafu)?; + let (parts, body) = response.into_parts(); + let GitHubErrorBody { + documentation_url, + errors, + message, + } = serde_json::from_slice(body.collect().await?.to_bytes().as_ref()) + .context(error::SerdeSnafu)?; Err(error::Error::GitHub { - source: b, + source: GitHubError { + status_code: parts.status, + documentation_url, + errors, + message, + }, backtrace: Backtrace::generate(), }) } diff --git a/tests/commit_associated_check_runs_tests.rs b/tests/commit_associated_check_runs_tests.rs index 2ff6aff3..a182f434 100644 --- a/tests/commit_associated_check_runs_tests.rs +++ b/tests/commit_associated_check_runs_tests.rs @@ -95,7 +95,8 @@ async fn should_fail_when_not_found() { match result.unwrap_err() { Error::GitHub { source, .. } => { - assert_eq!("Its gone", source.message) + assert_eq!(http::StatusCode::NOT_FOUND, source.status_code); + assert_eq!("Its gone", source.message); } other => panic!("Unexpected error: {:?}", other), }