3D 结果序列化失败不再落「完成但 result 为空」的终态
- job_result_payload 改为返回 Result,失败按 500 上报服务端问题,去掉 result:null 兜底形状 - worker 持久化前用 ? 把失败交给既有失败链路:任务按失败终态处理并冲正扣费 - worker 测试夹具同步改为 expect,断言完成结果可序列化
This commit is contained in:
@@ -3,13 +3,16 @@
|
||||
//! 结果按端点使用严格 tagged enum,只带正式资源引用与已落地对象元数据;
|
||||
//! provider task ID、带签名的临时地址与 SDK 类型都不进入结果。
|
||||
|
||||
use axum::http::StatusCode;
|
||||
use serde_json::{Value, json};
|
||||
use shared_contracts::model3d::Model3dGenerationResult;
|
||||
use shared_contracts::model3d::common::{Model3dGeneratedArtifact, Model3dGenerationTargetRef};
|
||||
use shared_contracts::model3d::image_to_model::Model3dImageToModelResult;
|
||||
use shared_contracts::model3d::text_to_model::Model3dTextToModelResult;
|
||||
|
||||
use super::{job::Model3dJobKind, storage::StoredModel3dArtifact};
|
||||
use crate::http_error::AppError;
|
||||
|
||||
use super::{job::Model3dJobKind, provider::TRIPO_PROVIDER, storage::StoredModel3dArtifact};
|
||||
|
||||
pub(crate) fn artifact_metadata(stored: &StoredModel3dArtifact) -> Model3dGeneratedArtifact {
|
||||
Model3dGeneratedArtifact {
|
||||
@@ -47,13 +50,15 @@ pub(crate) fn build_result(
|
||||
}
|
||||
|
||||
/// 队列终态结果载荷:外层固定 `result` 字段,值就是严格类型化的完成结果。
|
||||
pub(crate) fn job_result_payload(result: Model3dGenerationResult) -> Value {
|
||||
match serde_json::to_value(result) {
|
||||
Ok(value) => json!({ "result": value }),
|
||||
// 结果由字符串与数字组成,序列化失败属于实现错误;仍返回可对账的稳定形状。
|
||||
Err(error) => json!({
|
||||
"result": null,
|
||||
"resultSerializeError": error.to_string(),
|
||||
}),
|
||||
}
|
||||
///
|
||||
/// 序列化失败按服务端问题上报,由 worker 把任务标记为失败 —— 不能落一条
|
||||
/// 「完成但 `result: null`」的终态,消费方会当成成功却反序列化不出结果。
|
||||
pub(crate) fn job_result_payload(result: Model3dGenerationResult) -> Result<Value, AppError> {
|
||||
let value = serde_json::to_value(result).map_err(|error| {
|
||||
AppError::from_status(StatusCode::INTERNAL_SERVER_ERROR).with_details(json!({
|
||||
"provider": TRIPO_PROVIDER,
|
||||
"message": format!("序列化 3D 生成结果失败:{error}"),
|
||||
}))
|
||||
})?;
|
||||
Ok(json!({ "result": value }))
|
||||
}
|
||||
|
||||
@@ -365,7 +365,7 @@ async fn persist_result(
|
||||
_ => EditorCanvasLayoutPlan::None,
|
||||
};
|
||||
let job_result_payload_json =
|
||||
editor_generation_job_result_payload_json(caller, job_result_payload(result));
|
||||
editor_generation_job_result_payload_json(caller, job_result_payload(result)?);
|
||||
persist_editor_generation_result_atomically(
|
||||
state,
|
||||
caller,
|
||||
@@ -499,7 +499,7 @@ mod tests {
|
||||
&model,
|
||||
&preview,
|
||||
);
|
||||
let payload = job_result_payload(result);
|
||||
let payload = job_result_payload(result).expect("完成结果应可序列化");
|
||||
let result = &payload["result"];
|
||||
|
||||
assert_eq!(result["kind"], json!(expected_kind));
|
||||
|
||||
Reference in New Issue
Block a user