修复问题:阿里云未配置/禁用会被记录成可重试的外部 503 失败。
This commit is contained in:
@@ -17,12 +17,9 @@ pub(crate) async fn segment_image_with_aliyun_matting(
|
||||
image: &DownloadedOpenAiImage,
|
||||
log_label: &str,
|
||||
) -> Result<DownloadedOpenAiImage, AppError> {
|
||||
let matting_client = state.matting_client().ok_or_else(|| {
|
||||
AppError::from_status(StatusCode::SERVICE_UNAVAILABLE).with_details(json!({
|
||||
"provider": "aliyun-matting",
|
||||
"message": "阿里云抠图客户端未配置或未启用。",
|
||||
}))
|
||||
})?;
|
||||
let matting_client = state
|
||||
.matting_client()
|
||||
.ok_or_else(aliyun_matting_unconfigured_error)?;
|
||||
|
||||
let file_name = format!("{log_label}.png");
|
||||
let started_at = std::time::Instant::now();
|
||||
@@ -81,6 +78,14 @@ fn aliyun_matting_error_is_transport(message: &str) -> bool {
|
||||
aliyun_matting_error_http_status(message).is_none()
|
||||
}
|
||||
|
||||
fn aliyun_matting_unconfigured_error() -> AppError {
|
||||
AppError::from_status(StatusCode::SERVICE_UNAVAILABLE).with_details(json!({
|
||||
"provider": "aliyun-matting",
|
||||
"message": "阿里云抠图客户端未配置或未启用。",
|
||||
"externalCallAttempted": false,
|
||||
}))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -122,4 +127,11 @@ mod tests {
|
||||
"通用抠图接口返回失败(HTTP 429,Code=Throttled):QPS exceeded"
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn aliyun_matting_unconfigured_error_marks_no_external_call_attempt() {
|
||||
let error = aliyun_matting_unconfigured_error();
|
||||
|
||||
assert!(!crate::external_api_audit::matting_failure_external_call_attempted(&error));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2238,21 +2238,23 @@ async fn remove_editor_character_animation_frame_backgrounds(
|
||||
error_details = ?error.details(),
|
||||
"editor_animation_frame_aliyun_matting_fallback_to_local"
|
||||
);
|
||||
crate::external_api_audit::record_matting_external_api_failure(
|
||||
state,
|
||||
audit,
|
||||
"aliyun-matting",
|
||||
state.config.aliyun_matting_endpoint.clone(),
|
||||
"editor-character-animation-frame-matting",
|
||||
"aliyun_segment",
|
||||
crate::external_api_audit::matting_failure_audit_status_code(&error),
|
||||
crate::external_api_audit::matting_failure_audit_timeout(&error),
|
||||
crate::external_api_audit::matting_failure_audit_latency_ms(&error),
|
||||
error.message().to_string(),
|
||||
crate::external_api_audit::matting_failure_audit_raw_excerpt(&error)
|
||||
.or_else(|| Some(format!("frame_index={frame_index}"))),
|
||||
)
|
||||
.await;
|
||||
if crate::external_api_audit::matting_failure_external_call_attempted(&error) {
|
||||
crate::external_api_audit::record_matting_external_api_failure(
|
||||
state,
|
||||
audit,
|
||||
"aliyun-matting",
|
||||
state.config.aliyun_matting_endpoint.clone(),
|
||||
"editor-character-animation-frame-matting",
|
||||
"aliyun_segment",
|
||||
crate::external_api_audit::matting_failure_audit_status_code(&error),
|
||||
crate::external_api_audit::matting_failure_audit_timeout(&error),
|
||||
crate::external_api_audit::matting_failure_audit_latency_ms(&error),
|
||||
error.message().to_string(),
|
||||
crate::external_api_audit::matting_failure_audit_raw_excerpt(&error)
|
||||
.or_else(|| Some(format!("frame_index={frame_index}"))),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
remove_editor_generated_green_screen_background(&image, screen_color)?
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2304,20 +2304,22 @@ async fn fallback_editor_screen_background_removal(
|
||||
error_details = ?error.details(),
|
||||
"editor_aliyun_matting_fallback_to_local_screen_background_removal"
|
||||
);
|
||||
crate::external_api_audit::record_matting_external_api_failure(
|
||||
state,
|
||||
audit,
|
||||
"aliyun-matting",
|
||||
state.config.aliyun_matting_endpoint.clone(),
|
||||
"editor-screen-background-removal",
|
||||
"aliyun_segment",
|
||||
crate::external_api_audit::matting_failure_audit_status_code(&error),
|
||||
crate::external_api_audit::matting_failure_audit_timeout(&error),
|
||||
crate::external_api_audit::matting_failure_audit_latency_ms(&error),
|
||||
error.message().to_string(),
|
||||
crate::external_api_audit::matting_failure_audit_raw_excerpt(&error),
|
||||
)
|
||||
.await;
|
||||
if crate::external_api_audit::matting_failure_external_call_attempted(&error) {
|
||||
crate::external_api_audit::record_matting_external_api_failure(
|
||||
state,
|
||||
audit,
|
||||
"aliyun-matting",
|
||||
state.config.aliyun_matting_endpoint.clone(),
|
||||
"editor-screen-background-removal",
|
||||
"aliyun_segment",
|
||||
crate::external_api_audit::matting_failure_audit_status_code(&error),
|
||||
crate::external_api_audit::matting_failure_audit_timeout(&error),
|
||||
crate::external_api_audit::matting_failure_audit_latency_ms(&error),
|
||||
error.message().to_string(),
|
||||
crate::external_api_audit::matting_failure_audit_raw_excerpt(&error),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
remove_editor_generated_green_screen_background(image, screen_color)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,6 +248,14 @@ pub(crate) fn matting_failure_audit_latency_ms(error: &AppError) -> Option<u64>
|
||||
.and_then(Value::as_u64)
|
||||
}
|
||||
|
||||
pub(crate) fn matting_failure_external_call_attempted(error: &AppError) -> bool {
|
||||
error
|
||||
.details()
|
||||
.and_then(|details| details.get("externalCallAttempted"))
|
||||
.and_then(Value::as_bool)
|
||||
.unwrap_or(true)
|
||||
}
|
||||
|
||||
pub(crate) fn matting_failure_audit_raw_excerpt(error: &AppError) -> Option<String> {
|
||||
error
|
||||
.details()
|
||||
@@ -741,4 +749,20 @@ mod tests {
|
||||
assert_eq!(tracking.metadata["retryable"], false);
|
||||
assert_eq!(tracking.metadata["latencyMs"], 67);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matting_failure_external_call_attempted_defaults_to_true() {
|
||||
let attempted = AppError::from_status(StatusCode::BAD_GATEWAY).with_details(json!({
|
||||
"provider": "aliyun-matting",
|
||||
"message": "真实上游失败",
|
||||
}));
|
||||
let skipped = AppError::from_status(StatusCode::SERVICE_UNAVAILABLE).with_details(json!({
|
||||
"provider": "aliyun-matting",
|
||||
"message": "阿里云抠图客户端未配置或未启用。",
|
||||
"externalCallAttempted": false,
|
||||
}));
|
||||
|
||||
assert!(matting_failure_external_call_attempted(&attempted));
|
||||
assert!(!matting_failure_external_call_attempted(&skipped));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user