3D 图生输入解析把「缺对象键」改判为服务端问题

- resolve_source_object_key_with 在记录已解析但缺对象键时返回 502 与 model3d-image-source-object-key-missing,不再复用「引用不可用」的 400
- 未登记 / 跨 owner / 已删除仍收敛成同一句 400;缺对象键口径与 editor_project::validate_editor_reference_id_for_owner 的 BAD_GATEWAY 对齐
- 定向用例改名为 image_source_resolution_reports_missing_object_key_as_server_side_failure,断言状态码与 reason
This commit is contained in:
2026-09-23 14:49:18 +08:00
parent 9edb4e5f80
commit 8a8c00fbb6
@@ -129,10 +129,12 @@ where
if resolved.kind != requested_kind {
return Err(image_source_kind_mismatch(requested_kind, resolved.kind));
}
resolved.object_key.ok_or_else(image_source_unavailable)
resolved
.object_key
.ok_or_else(image_source_object_key_missing)
}
/// 未登记、跨 owner已删除与缺少对象键都收敛成同一句 400。
/// 未登记、跨 owner已删除都收敛成同一句 400。
fn image_source_unavailable() -> AppError {
AppError::from_status(StatusCode::BAD_REQUEST).with_details(json!({
"provider": TRIPO_PROVIDER,
@@ -142,6 +144,19 @@ fn image_source_unavailable() -> AppError {
}))
}
/// 记录已解析且归属调用方,但缺少对象键:这是 SpacetimeDB 行本身不完整,不是用户的引用不可用。
///
/// 归到 400 会让客户端照着「必须是已登记资源」去改一个改不动的地方,也丢掉「行存在但格式异常」
/// 这个运维信号;口径与 `editor_project::validate_editor_reference_id_for_owner` 一致,按 5xx 上报。
fn image_source_object_key_missing() -> AppError {
AppError::from_status(StatusCode::BAD_GATEWAY).with_details(json!({
"provider": TRIPO_PROVIDER,
"reason": "model3d-image-source-object-key-missing",
"field": "source",
"message": "该图片引用已登记但缺少对象键,请稍后重试或联系支持。",
}))
}
/// `kind` 与 ID 实际指向的记录类型不一致;两者都由调用方给出,不涉及他人数据是否存在。
fn image_source_kind_mismatch(requested_kind: &str, resolved_kind: &str) -> AppError {
AppError::from_status(StatusCode::BAD_REQUEST).with_details(json!({
@@ -217,9 +232,9 @@ mod tests {
);
}
/// 记录存在但缺对象键与「引用不可用」收敛成同一句 400
/// 记录存在但缺对象键是服务端数据问题:报 5xx,不用「引用不可用」的 400 误导客户端
#[tokio::test]
async fn image_source_resolution_treats_missing_object_key_as_unavailable() {
async fn image_source_resolution_reports_missing_object_key_as_server_side_failure() {
let source = Model3dGenerationSource::Resource {
resource_id: "res-1".to_string(),
};
@@ -227,10 +242,13 @@ mod tests {
let error =
resolve_source_object_key_with(&source, |_| async { Ok(resolved("resource", None)) })
.await
.expect_err("缺对象键时必须按引用不可用处理");
.expect_err("缺对象键时必须按服务端问题处理");
assert_eq!(error.status_code(), StatusCode::BAD_REQUEST);
assert_eq!(reason_of(&error), Some("model3d-image-source-unavailable"));
assert_eq!(error.status_code(), StatusCode::BAD_GATEWAY);
assert_eq!(
reason_of(&error),
Some("model3d-image-source-object-key-missing")
);
}
/// 未登记 / 跨 owner / 已删除这类 4xx 收敛成同一句 400;基础设施故障保留原状态码。