修复了一个project_detail_data create失败报错的问题

This commit is contained in:
strepsiades
2026-03-31 15:54:12 +08:00
parent f0ce8dc37e
commit eb02fd32a5
3 changed files with 59 additions and 3 deletions
+2 -2
View File
@@ -73,12 +73,12 @@ class ProjectResponseBase(BaseResponseWithID):
progress_type: ProgressType | None = Field(None, description="推进分类", examples=[ProgressType.A]) progress_type: ProgressType | None = Field(None, description="推进分类", examples=[ProgressType.A])
key_constraints: KeyConstraints = Field(KeyConstraints.NONE, description="关键制约", examples=[KeyConstraints.NONE]) key_constraints: KeyConstraints = Field(KeyConstraints.NONE, description="关键制约", examples=[KeyConstraints.NONE])
key_constraints_remark: Optional[str] = Field("", description="关键制约备注", examples=[""]) key_constraints_remark: Optional[str] = Field("", description="关键制约备注", examples=[""])
status: Optional[str] = Field(None, description="项目状态") # status: Optional[str] = Field(None, description="项目状态")
apply_file_ids: List[str] = Field(default_factory=list, description="申请表附件ID列表", examples=[[]]) apply_file_ids: List[str] = Field(default_factory=list, description="申请表附件ID列表", examples=[[]])
# 拓展信息 # 拓展信息
dbtc_score_list: Optional[list] = Field(default_factory=list, description='达标投产评分列表') # 这里项目用的是list而不是List dbtc_score_list: Optional[list] = Field(default_factory=list, description='达标投产评分列表') # 这里项目用的是list而不是List
approval_status: Optional[str] = Field(None, description="审核状态", examples=["pending"]) # : Optional[str] = Field(None, description="审核状态", examples=["pending"])
@@ -207,7 +207,16 @@ class ProjectDetailApiHandler(BaseApiHandler):
self._mark_approval_snapshot_synced(node) self._mark_approval_snapshot_synced(node)
except Exception as e: except Exception as e:
self._pending_push_context.pop(push_id, None) self._pending_push_context.pop(push_id, None)
results.append(TaskResult.failed(node_id=node.node_id, error=str(e))) results.append(
TaskResult.failed(
node_id=node.node_id,
error=str(e),
push_id=push_id,
biz_id=biz_id,
key=str(key),
project_id=str(project_id),
)
)
return results return results
@@ -1,10 +1,13 @@
from __future__ import annotations from __future__ import annotations
from pydantic import BaseModel from pydantic import BaseModel
import pytest
from sync_state_machine.common.collection import DataCollection from sync_state_machine.common.collection import DataCollection
from sync_state_machine.common.sync_node import SyncNode from sync_state_machine.common.sync_node import SyncNode
from sync_state_machine.domain.project_detail.api_handler import ProjectDetailApiHandler from sync_state_machine.domain.project_detail.api_handler import ProjectDetailApiHandler
from sync_state_machine.domain.project_detail.sync_node import ProjectDetailSyncNode
from sync_state_machine.datasource.task_result import TaskStatus
class _ProjectSchema(BaseModel): class _ProjectSchema(BaseModel):
@@ -47,3 +50,47 @@ def test_project_detail_load_injects_project_id_before_validation() -> None:
assert detail_data is not None assert detail_data is not None
assert detail_data["project_id"] == "project-1" assert detail_data["project_id"] == "project-1"
assert detail_data["id"] == "detail-1" assert detail_data["id"] == "detail-1"
class _FailingApiClient:
async def request(self, method, endpoint, params=None, data=None, **kwargs):
return {"code": 500, "message": "boom"}
@pytest.mark.asyncio
async def test_project_detail_create_failure_preserves_push_id_and_biz_id() -> None:
collection = DataCollection("remote")
project = _ProjectNode(
node_id="project-node-1",
data_id="project-1",
data={"id": "project-1"},
context={"all_info": {"project_detail": []}},
)
await collection.add(project)
node = ProjectDetailSyncNode(
node_id="detail-node-1",
data_id="local-detail-1",
data={
"id": "local-detail-1",
"project_id": "project-1",
"key": "production",
"value": [{"date": "2026-01-01", "capacity": 1.0}],
},
)
handler = ProjectDetailApiHandler()
handler.set_collection(collection)
handler.api_client = _FailingApiClient()
results = await handler.create_all([node])
assert len(results) == 1
result = results[0]
assert result.status == TaskStatus.FAILED
assert result.error == "API error: boom"
assert isinstance(result.push_id, str) and result.push_id
assert result.metadata["biz_id"] == "project-1"
assert result.metadata["project_id"] == "project-1"
assert result.metadata["key"] == "production"