diff --git a/crates/crates_io_og_image/src/lib.rs b/crates/crates_io_og_image/src/lib.rs index 0f85fa9c7b2..4ff073e1198 100644 --- a/crates/crates_io_og_image/src/lib.rs +++ b/crates/crates_io_og_image/src/lib.rs @@ -8,6 +8,7 @@ pub use error::OgImageError; use crate::formatting::{serialize_bytes, serialize_number, serialize_optional_number}; use bytes::Bytes; use crates_io_env_vars::var; +use reqwest::StatusCode; use serde::Serialize; use std::collections::HashMap; use std::path::{Path, PathBuf}; @@ -252,19 +253,25 @@ impl OgImageGenerator { } else { debug!(url = %avatar, "Downloading avatar from URL: {avatar}"); // Download the avatar from the URL - let response = client - .get(*avatar) - .send() - .await - .map_err(|err| OgImageError::AvatarDownloadError { + let response = client.get(*avatar).send().await.map_err(|err| { + OgImageError::AvatarDownloadError { url: avatar.to_string(), source: err, - })? - .error_for_status() - .map_err(|err| OgImageError::AvatarDownloadError { + } + })?; + + let status = response.status(); + if status == StatusCode::NOT_FOUND { + warn!(url = %avatar, "Avatar URL returned 404 Not Found"); + continue; // Skip this avatar if not found + } + + if let Err(err) = response.error_for_status_ref() { + return Err(OgImageError::AvatarDownloadError { url: avatar.to_string(), source: err, - })?; + }); + } let content_length = response.content_length(); debug!( diff --git a/crates/crates_io_og_image/template/og-image.typ b/crates/crates_io_og_image/template/og-image.typ index 0eeab1acbb5..3b965896737 100644 --- a/crates/crates_io_og_image/template/og-image.typ +++ b/crates/crates_io_og_image/template/og-image.typ @@ -283,7 +283,10 @@ let authors-with-avatars = data.authors.map(author => { let avatar = none if author.avatar != none { - avatar = "assets/" + avatar_map.at(author.avatar) + let avatar_path = avatar_map.at(author.avatar, default: none) + if avatar_path != none { + avatar = "assets/" + avatar_path + } } (name: author.name, avatar: avatar) })