修复图片编辑缺少参考图时的 panic

platform-image 新增 missing_reference_images_error 并在 create_image_edit_with_references_and_model 中复用

api-server 两个多参考图编辑入口在解析 provider 客户端前先校验参考图,返回 400 而不是 panic

恢复 vector_engine_multi_reference_edit_rejects_empty_references 期望的缺少参考图错误
This commit is contained in:
2026-09-19 13:41:21 +08:00
parent 5ce267ae85
commit 1a2e60bf05
6 changed files with 54 additions and 9 deletions
@@ -5,7 +5,7 @@ use platform_image::{
VECTOR_ENGINE_PROVIDER, build_image_http_client, create_image_edit,
create_image_edit_with_references, create_image_edit_with_references_and_model,
create_image_generation, create_image_generation_with_model,
create_nanobanana_generate_content,
create_nanobanana_generate_content, missing_reference_images_error,
};
#[cfg(test)]
use platform_image::{build_image_request_body, images_edit_url, images_generation_url};
@@ -320,6 +320,21 @@ pub(crate) async fn create_openai_image_edit_with_references(
"negativePromptChars": negative_prompt.map(str::chars).map(Iterator::count),
"referenceImageCount": reference_images.len(),
});
// 中文注释:先做本地参考图校验,避免 provider 客户端缺失时在校验前 panic。
if reference_images.is_empty() {
return map_platform_image_result(
settings,
Err(missing_reference_images_error(
ImageProvider::Tiantoken,
failure_context,
)),
"image_edit_with_references",
failure_context,
request_payload,
started_at_micros,
)
.await;
}
let provider_client = settings.client_for_model(GPT_IMAGE_2_5_EDIT_MODEL);
let provider_settings = settings.provider_settings_for_model(GPT_IMAGE_2_5_EDIT_MODEL);
let result = create_image_edit_with_references(
@@ -364,6 +379,21 @@ pub(crate) async fn create_openai_image_edit_with_references_and_model(
"negativePromptChars": negative_prompt.map(str::chars).map(Iterator::count),
"referenceImageCount": reference_images.len(),
});
// 中文注释:先做本地参考图校验,避免 provider 客户端缺失时在校验前 panic。
if reference_images.is_empty() {
return map_platform_image_result(
settings,
Err(missing_reference_images_error(
ImageProvider::Tiantoken,
failure_context,
)),
"image_edit_with_references",
failure_context,
request_payload,
started_at_micros,
)
.await;
}
let provider_client = settings.client_for_model(model);
let provider_settings = settings.provider_settings_for_model(model);
let result = create_image_edit_with_references_and_model(
@@ -26,5 +26,6 @@ pub use runtime::{
create_image_edit, create_image_edit_with_references,
create_image_edit_with_references_and_model, create_image_generation,
create_image_generation_with_model, create_nanobanana_generate_content, download_remote_image,
missing_reference_images_error,
};
pub use transport::{build_image_http_client, build_image_provider_client};
@@ -1,6 +1,19 @@
use std::{error::Error, fmt};
use crate::image_provider::{audit::PlatformImageFailureAudit, util::is_timeout_message};
use crate::image_provider::{
audit::PlatformImageFailureAudit, types::ImageProvider, util::is_timeout_message,
};
/// 图片编辑缺少参考图时的统一错误;调用方可在解析 provider 客户端之前先行校验。
pub fn missing_reference_images_error(
provider: ImageProvider,
failure_context: &str,
) -> PlatformImageError {
PlatformImageError::InvalidRequest {
provider: provider.as_str(),
message: format!("{failure_context}:缺少参考图,图片编辑需要至少一张参考图。"),
}
}
#[derive(Clone, Debug)]
pub enum PlatformImageError {
@@ -19,7 +19,7 @@ use crate::image_provider::{
map_curl_error, send_image_json_request_with_curl,
send_image_multipart_edit_request_with_curl,
},
error::PlatformImageError,
error::{PlatformImageError, missing_reference_images_error},
image_source::resolve_reference_images,
request::{
build_image_edit_request_log_params, build_image_request_body_with_model,
@@ -499,10 +499,10 @@ pub async fn create_image_edit_with_references_and_model(
}
})?;
if reference_images.is_empty() {
return Err(PlatformImageError::InvalidRequest {
provider: settings.provider.as_str(),
message: format!("{failure_context}:缺少参考图,图片编辑需要至少一张参考图。"),
});
return Err(missing_reference_images_error(
settings.provider,
failure_context,
));
}
if reference_images.len() > VECTOR_ENGINE_IMAGE_EDIT_MAX_REFERENCE_IMAGES {
return Err(PlatformImageError::InvalidRequest {
@@ -11,7 +11,7 @@ pub(crate) use crate::image_provider::transport::curl as curl_transport;
pub use audit::PlatformImageFailureAudit;
pub(crate) use audit::build_failure_audit;
pub(crate) use budget::{effective_request_timeout_ms, request_budget_exhausted_error};
pub use error::{PlatformImageError, PlatformImageStatusHint};
pub use error::{PlatformImageError, PlatformImageStatusHint, missing_reference_images_error};
pub use executor::{
create_image_edit, create_image_edit_with_references,
create_image_edit_with_references_and_model, create_image_generation,
+2 -1
View File
@@ -15,7 +15,8 @@ pub use image_provider::{
create_image_edit_with_references, create_image_edit_with_references_and_model,
create_image_generation, create_image_generation_with_model,
create_nanobanana_generate_content, download_remote_image, images_edit_url,
images_generation_url, nanobanana_generate_content_url, resolve_image_provider,
images_generation_url, missing_reference_images_error, nanobanana_generate_content_url,
resolve_image_provider,
};
pub use pixel_art_snapper::{
PIXEL_ART_ALPHA_COVERAGE_THRESHOLD, PIXEL_ART_ANALYSIS_COLORS, PIXEL_ART_KMEANS_SAMPLE_LIMIT,