diff --git a/api/src/client.rs b/api/src/client.rs index 879b7871..a09b7692 100644 --- a/api/src/client.rs +++ b/api/src/client.rs @@ -1,3 +1,4 @@ +use std::fmt; use std::path::Path; use std::sync::mpsc::Sender; @@ -11,6 +12,38 @@ use tokio::fs; use crate::call_api::CallApi; use crate::message; +#[derive(Debug)] +pub enum ApiErrorEndpoint { + CreateBundleUpload, + GetQuarantiningConfig, + PutBundleToS3, + TelemetryUploadMetrics, +} + +impl ApiErrorEndpoint { + pub fn unknown_error_reason(&self) -> String { + match self { + Self::CreateBundleUpload => "unknown_create_bundle_upload".into(), + Self::GetQuarantiningConfig => "unknown_get_quarantining_config".into(), + Self::PutBundleToS3 => "unknown_put_bundle_to_s3".into(), + Self::TelemetryUploadMetrics => "unknown_telemetry_upload_metrics".into(), + } + } +} + +impl fmt::Display for ApiErrorEndpoint { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::CreateBundleUpload => write!(f, "Error in create bundle upload endpoint"), + Self::GetQuarantiningConfig => write!(f, "Error in get quarantine config endpoint"), + Self::PutBundleToS3 => write!(f, "Error in put bundle to s3 endpoint"), + Self::TelemetryUploadMetrics => write!(f, "Error in telemetry upload metrics endpoint"), + } + } +} + +impl std::error::Error for ApiErrorEndpoint {} + pub struct ApiClient { pub api_host: String, pub telemetry_host: String, @@ -150,6 +183,7 @@ impl ApiClient { } .call_api() .await + .map_err(|e| e.context(ApiErrorEndpoint::CreateBundleUpload)) } pub async fn get_quarantining_config( @@ -192,6 +226,7 @@ impl ApiClient { } .call_api() .await + .map_err(|e| e.context(ApiErrorEndpoint::GetQuarantiningConfig)) } pub async fn put_bundle_to_s3, B: AsRef>( @@ -231,6 +266,7 @@ impl ApiClient { } .call_api() .await + .map_err(|e| e.context(ApiErrorEndpoint::PutBundleToS3)) } pub async fn telemetry_upload_metrics( @@ -285,6 +321,7 @@ impl ApiClient { } .call_api() .await + .map_err(|e| e.context(ApiErrorEndpoint::TelemetryUploadMetrics)) } async fn deserialize_response( @@ -453,21 +490,23 @@ mod tests { api_client.api_host.clone_from(&state.host); assert!( - api_client - .get_quarantining_config(&message::GetQuarantineConfigRequest { - repo: context::repo::RepoUrlParts { - host: String::from("host"), - owner: String::from("owner"), - name: String::from("name"), - }, - org_url_slug: String::from("org_url_slug"), - test_identifiers: vec![], - remote_urls: vec![], - }) - .await - .unwrap_err() - .to_string() - .contains("501 Not Implemented") + format!( + "{:?}", + api_client + .get_quarantining_config(&message::GetQuarantineConfigRequest { + repo: context::repo::RepoUrlParts { + host: String::from("host"), + owner: String::from("owner"), + name: String::from("name"), + }, + org_url_slug: String::from("org_url_slug"), + test_identifiers: vec![], + remote_urls: vec![], + }) + .await + .unwrap_err() + ) + .contains("501 Not Implemented") ); assert_eq!(CALL_COUNT.load(Ordering::Relaxed), 1); } @@ -499,21 +538,23 @@ mod tests { api_client.api_host.clone_from(&state.host); assert!( - api_client - .get_quarantining_config(&message::GetQuarantineConfigRequest { - repo: context::repo::RepoUrlParts { - host: String::from("api_host"), - owner: String::from("owner"), - name: String::from("name"), - }, - remote_urls: vec![], - org_url_slug: String::from("org_url_slug"), - test_identifiers: vec![], - }) - .await - .unwrap_err() - .to_string() - .contains("500 Internal Server Error") + format!( + "{:?}", + api_client + .get_quarantining_config(&message::GetQuarantineConfigRequest { + repo: context::repo::RepoUrlParts { + host: String::from("api_host"), + owner: String::from("owner"), + name: String::from("name"), + }, + remote_urls: vec![], + org_url_slug: String::from("org_url_slug"), + test_identifiers: vec![], + }) + .await + .unwrap_err() + ) + .contains("500 Internal Server Error") ); assert_eq!(CALL_COUNT.load(Ordering::Relaxed), 6); } @@ -540,21 +581,23 @@ mod tests { api_client.api_host.clone_from(&state.host); assert!( - api_client - .get_quarantining_config(&message::GetQuarantineConfigRequest { - repo: context::repo::RepoUrlParts { - host: String::from("api_host"), - owner: String::from("owner"), - name: String::from("name"), - }, - remote_urls: vec![], - org_url_slug: String::from("org_url_slug"), - test_identifiers: vec![], - }) - .await - .unwrap_err() - .to_string() - .contains("404 Not Found") + format!( + "{:?}", + api_client + .get_quarantining_config(&message::GetQuarantineConfigRequest { + repo: context::repo::RepoUrlParts { + host: String::from("api_host"), + owner: String::from("owner"), + name: String::from("name"), + }, + remote_urls: vec![], + org_url_slug: String::from("org_url_slug"), + test_identifiers: vec![], + }) + .await + .unwrap_err() + ) + .contains("404 Not Found") ); } } diff --git a/cli/src/upload_command.rs b/cli/src/upload_command.rs index e4bdeefc..b1f0e563 100644 --- a/cli/src/upload_command.rs +++ b/cli/src/upload_command.rs @@ -3,7 +3,7 @@ use std::env; use std::path::PathBuf; use std::sync::mpsc::Sender; -use api::client::ApiClient; +use api::client::{ApiClient, ApiErrorEndpoint}; use api::{client::get_api_host, urls::url_for_test_case}; use bundle::{BundleMeta, BundlerUtil, Test, unzip_tarball}; use clap::{ArgAction, Args}; @@ -296,6 +296,12 @@ fn error_reason(error: &anyhow::Error) -> String { return status.to_string().replace(' ', "_").to_lowercase(); } } + + for cause in error.chain() { + if let Some(endpoint_context) = cause.downcast_ref::() { + return endpoint_context.unknown_error_reason(); + } + } "unknown".into() }