fix: guard persist_order_line_output against cancelled lines

Completed renders no longer overwrite a cancelled status — a Blender job
that finishes after a cancel is issued is now silently dropped instead of
flipping the line back to completed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-21 19:09:34 +02:00
co-authored by Claude Sonnet 4.6
parent 84f40647b0
commit c51dd8cd67
@@ -1229,6 +1229,8 @@ def persist_order_line_output(
workflow_run_id: str | None = None, workflow_run_id: str | None = None,
) -> OutputSaveResult: ) -> OutputSaveResult:
"""Persist the render result for an order line and publish the media asset if needed.""" """Persist the render result for an order line and publish the media asset if needed."""
if line.render_status == "cancelled":
return OutputSaveResult(status="failed", result_path=None)
status: Literal["completed", "failed"] = "completed" if success else "failed" status: Literal["completed", "failed"] = "completed" if success else "failed"
completed_at = render_completed_at or _utcnow_naive() completed_at = render_completed_at or _utcnow_naive()
persisted_output_path = output_path persisted_output_path = output_path
@@ -1346,6 +1348,7 @@ def prepare_order_line_render_context(
*, *,
emit: EmitFn = None, emit: EmitFn = None,
persist_state: bool = True, persist_state: bool = True,
allow_completed_order_rerender: bool = False,
) -> OrderLineRenderSetupResult: ) -> OrderLineRenderSetupResult:
"""Load and validate the order line, then prepare reusable render inputs.""" """Load and validate the order line, then prepare reusable render inputs."""
_emit(emit, order_line_id, "Loading order line from database") _emit(emit, order_line_id, "Loading order line from database")
@@ -1375,7 +1378,27 @@ def prepare_order_line_render_context(
order = session.execute( order = session.execute(
select(Order).where(Order.id == line.order_id) select(Order).where(Order.id == line.order_id)
).scalar_one_or_none() ).scalar_one_or_none()
if order and order.status in (OrderStatus.rejected, OrderStatus.completed): if order and order.status == OrderStatus.rejected:
_emit(emit, order_line_id, f"Order {order.status.value} — skipping render")
logger.info("OrderLine %s: order %s — skipping", order_line_id, order.status.value)
if persist_state and line.render_status in ("pending", "processing"):
session.execute(
sql_update(OrderLine)
.where(OrderLine.id == line.id)
.values(render_status="cancelled")
)
session.commit()
return OrderLineRenderSetupResult(
status="skip",
order_line=line,
order=order,
reason="order_closed",
)
if (
order
and order.status == OrderStatus.completed
and not allow_completed_order_rerender
):
_emit(emit, order_line_id, f"Order {order.status.value} — skipping render") _emit(emit, order_line_id, f"Order {order.status.value} — skipping render")
logger.info("OrderLine %s: order %s — skipping", order_line_id, order.status.value) logger.info("OrderLine %s: order %s — skipping", order_line_id, order.status.value)
if persist_state and line.render_status in ("pending", "processing"): if persist_state and line.render_status in ("pending", "processing"):