From 6bd1b225e8ddffaa0c69f6328ceb9b55fa2d3301 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Mon, 16 Mar 2026 21:56:50 -0400 Subject: [PATCH] improve errors --- Cargo.lock | 1 + .../artcraft/artcraft_router/Cargo.toml | 1 + .../src/errors/artcraft_router_error.rs | 15 +++++-- .../src/errors/download_error.rs | 40 +++++++++++++++++++ .../artcraft_router/src/errors/mod.rs | 1 + .../src/utils/download_file.rs | 23 ++++++++--- 6 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 crates/api_clients/artcraft/artcraft_router/src/errors/download_error.rs diff --git a/Cargo.lock b/Cargo.lock index a861579b9a..2ae89ced2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -801,6 +801,7 @@ dependencies = [ "uuid 1.18.1", "workspace-build-acceleration", "world_labs_api", + "wreq", ] [[package]] diff --git a/crates/api_clients/artcraft/artcraft_router/Cargo.toml b/crates/api_clients/artcraft/artcraft_router/Cargo.toml index 67ddad74c5..56bb7d406e 100644 --- a/crates/api_clients/artcraft/artcraft_router/Cargo.toml +++ b/crates/api_clients/artcraft/artcraft_router/Cargo.toml @@ -30,6 +30,7 @@ anyhow.workspace = true log.workspace = true reqwest.workspace = true serde.workspace = true +wreq.workspace = true serde_derive.workspace = true tokio.workspace = true uuid.workspace = true diff --git a/crates/api_clients/artcraft/artcraft_router/src/errors/artcraft_router_error.rs b/crates/api_clients/artcraft/artcraft_router/src/errors/artcraft_router_error.rs index cccfb544b6..111d8d4941 100644 --- a/crates/api_clients/artcraft/artcraft_router/src/errors/artcraft_router_error.rs +++ b/crates/api_clients/artcraft/artcraft_router/src/errors/artcraft_router_error.rs @@ -1,4 +1,5 @@ use crate::errors::client_error::ClientError; +use crate::errors::download_error::DownloadError; use crate::errors::provider_error::ProviderError; use std::error::Error; use std::fmt::{Display, Formatter}; @@ -8,6 +9,9 @@ pub enum ArtcraftRouterError { /// A client configuration error. Client(ClientError), + /// Failed to download a file from a URL (e.g. when re-uploading to a provider's CDN). + Download(DownloadError), + /// The requested model is not yet supported by the router. UnsupportedModel(String), @@ -16,9 +20,6 @@ pub enum ArtcraftRouterError { /// An error from an underlying provider. Provider(ProviderError), - - /// Failed to download a file from a URL (e.g. when re-uploading to a provider's CDN). - FileDownload(String), } impl Error for ArtcraftRouterError {} @@ -27,10 +28,10 @@ impl Display for ArtcraftRouterError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { Self::Client(e) => write!(f, "Client error: {}", e), + Self::Download(e) => write!(f, "Download error: {}", e), Self::UnsupportedModel(model) => write!(f, "Unsupported model: {}", model), Self::InvalidInput(msg) => write!(f, "Invalid input: {}", msg), Self::Provider(e) => write!(f, "Provider error: {}", e), - Self::FileDownload(msg) => write!(f, "File download error: {}", msg), } } } @@ -41,6 +42,12 @@ impl From for ArtcraftRouterError { } } +impl From for ArtcraftRouterError { + fn from(error: DownloadError) -> Self { + Self::Download(error) + } +} + impl From for ArtcraftRouterError { fn from(error: ProviderError) -> Self { Self::Provider(error) diff --git a/crates/api_clients/artcraft/artcraft_router/src/errors/download_error.rs b/crates/api_clients/artcraft/artcraft_router/src/errors/download_error.rs new file mode 100644 index 0000000000..302effc121 --- /dev/null +++ b/crates/api_clients/artcraft/artcraft_router/src/errors/download_error.rs @@ -0,0 +1,40 @@ +use std::error::Error; +use std::fmt::{Display, Formatter}; + +#[derive(Debug)] +pub enum DownloadError { + BadStatus { + url: String, + status_code: u16, + }, + + ReqwestDownload { + url: String, + error: reqwest::Error, + maybe_status: Option, + }, + + WreqDownload { + url: String, + error: wreq::Error, + maybe_status: Option, + }, +} + +impl Error for DownloadError {} + +impl Display for DownloadError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Self::BadStatus { url, status_code } => { + write!(f, "Download failed for {} with status {}", url, status_code) + } + Self::ReqwestDownload { url, error, maybe_status } => { + write!(f, "Reqwest download error for {}: {} (status: {:?})", url, error, maybe_status) + } + Self::WreqDownload { url, error, maybe_status } => { + write!(f, "Wreq download error for {}: {} (status: {:?})", url, error, maybe_status) + } + } + } +} diff --git a/crates/api_clients/artcraft/artcraft_router/src/errors/mod.rs b/crates/api_clients/artcraft/artcraft_router/src/errors/mod.rs index e1733dacc0..29c2b05109 100644 --- a/crates/api_clients/artcraft/artcraft_router/src/errors/mod.rs +++ b/crates/api_clients/artcraft/artcraft_router/src/errors/mod.rs @@ -1,3 +1,4 @@ pub mod artcraft_router_error; pub mod client_error; +pub mod download_error; pub mod provider_error; diff --git a/crates/api_clients/artcraft/artcraft_router/src/utils/download_file.rs b/crates/api_clients/artcraft/artcraft_router/src/utils/download_file.rs index ec33419a5f..e71b39582b 100644 --- a/crates/api_clients/artcraft/artcraft_router/src/utils/download_file.rs +++ b/crates/api_clients/artcraft/artcraft_router/src/utils/download_file.rs @@ -1,19 +1,30 @@ use crate::errors::artcraft_router_error::ArtcraftRouterError; +use crate::errors::download_error::DownloadError; /// Download a file from a URL, returning its bytes. pub async fn download_file(url: &str) -> Result, ArtcraftRouterError> { let response = reqwest::get(url) .await - .map_err(|err| ArtcraftRouterError::FileDownload(format!("Failed to download {}: {}", url, err)))?; + .map_err(|err| DownloadError::ReqwestDownload { + url: url.to_string(), + maybe_status: err.status(), + error: err, + })?; - if !response.status().is_success() { - return Err(ArtcraftRouterError::FileDownload( - format!("Download failed for {} with status {}", url, response.status()) - )); + let status = response.status(); + if !status.is_success() { + return Err(DownloadError::BadStatus { + url: url.to_string(), + status_code: status.as_u16(), + }.into()); } response.bytes() .await .map(|b| b.to_vec()) - .map_err(|err| ArtcraftRouterError::FileDownload(format!("Failed to read bytes from {}: {}", url, err))) + .map_err(|err| DownloadError::ReqwestDownload { + url: url.to_string(), + maybe_status: err.status(), + error: err, + }.into()) }