Fix unit test for GhApiClient::get_repo_info

Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
Jiahao XU 2024-05-30 00:04:54 +10:00
parent 0bc4231b65
commit 7e4020f2a6
No known key found for this signature in database
GPG key ID: 76D1E687CA3C4928
2 changed files with 28 additions and 15 deletions

View file

@ -80,12 +80,9 @@ where
} }
#[derive(Deserialize)] #[derive(Deserialize)]
enum GraphQLResponse<T> { struct GraphQLResponse<T> {
#[serde(rename = "data")] data: T,
Data(T), errors: Option<GhGraphQLErrors>,
#[serde(rename = "errors")]
Errors(GhGraphQLErrors),
} }
#[derive(Serialize)] #[derive(Serialize)]
@ -131,14 +128,12 @@ where
let response = res?.await?; let response = res?.await?;
check_http_status_and_header(response.status(), response.headers())?; check_http_status_and_header(response.status(), response.headers())?;
let response: GraphQLResponse<T> = response.json().await?; let mut response: GraphQLResponse<T> = response.json().await?;
match response { if let Some(error) = response.errors.take() {
GraphQLResponse::Data(data) => Ok(data), Err(error.into())
GraphQLResponse::Errors(errors) if errors.is_rate_limited() => { } else {
Err(GhApiError::RateLimit { retry_after: None }) Ok(response.data)
}
GraphQLResponse::Errors(errors) => Err(errors.into()),
} }
} }
} }

View file

@ -30,7 +30,7 @@ pub enum GhApiError {
Context(Box<GhApiContextError>), Context(Box<GhApiContextError>),
#[error("Remote failed to process GraphQL query: {0}")] #[error("Remote failed to process GraphQL query: {0}")]
GraphQLErrors(#[from] GhGraphQLErrors), GraphQLErrors(GhGraphQLErrors),
#[error("Hit rate-limit, retry after {retry_after:?}")] #[error("Hit rate-limit, retry after {retry_after:?}")]
RateLimit { retry_after: Option<Duration> }, RateLimit { retry_after: Option<Duration> },
@ -58,15 +58,33 @@ impl GhApiError {
} }
} }
impl From<GhGraphQLErrors> for GhApiError {
fn from(e: GhGraphQLErrors) -> Self {
if e.is_rate_limited() {
Self::RateLimit { retry_after: None }
} else if e.is_not_found_error() {
Self::NotFound
} else {
Self::GraphQLErrors(e)
}
}
}
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct GhGraphQLErrors(Box<[GraphQLError]>); pub struct GhGraphQLErrors(Box<[GraphQLError]>);
impl GhGraphQLErrors { impl GhGraphQLErrors {
pub(super) fn is_rate_limited(&self) -> bool { fn is_rate_limited(&self) -> bool {
self.0 self.0
.iter() .iter()
.any(|error| matches!(error.error_type, GraphQLErrorType::RateLimited)) .any(|error| matches!(error.error_type, GraphQLErrorType::RateLimited))
} }
fn is_not_found_error(&self) -> bool {
self.0
.iter()
.any(|error| matches!(&error.error_type, GraphQLErrorType::Other(error_type) if *error_type == "NOT_FOUND"))
}
} }
impl error::Error for GhGraphQLErrors {} impl error::Error for GhGraphQLErrors {}