generated from john/python-template
Fix workflow commit atomicity, error path leak, and UI error boundary
Quality Gate / gate (push) Failing after 48s
Quality Gate / gate (push) Failing after 48s
Phase 1 of docs/reviews/2026-08-23-code-review.md. HIGH-01: process_queued_job committed page evidence and the terminal job status in separate transactions, so a crash between them left a transcript persisted against a job stuck in PROCESSING that the worker never reclaims. The final page's write is now deferred into _finalize_batch_outcome so it shares the terminal transaction. Intermediate pages remain individually durable, and the terminal commit is shielded against cancellation the same way per-page writes already were. HIGH-04: added tests/integration/test_pipeline_atomicity.py covering both Transaction B and Transaction C. Confirmed failing against the previous implementation before the fix. HIGH-03: classify_unexpected_error interpolated the raw exception into AppError.message, which the UI renders and the API serializes, leaking the database path from OperationalError. message is now generic. Because message also feeds format_error_detail, which writes evidence records, the root cause is preserved on a new internal-only AppError.detail field rather than discarded. HIGH-02: replaced 8 hand-rolled ui.notify error calls in home_page and people_page with error_presenter.show_error, restoring the correlation error_id, canonical category, and suggestion. Added an AST guard to test_ui_boundaries.py so pages cannot hand-roll error notifications again. Docs updated per documentation-sync: the message/detail split in docs/error_handling.md and the multi-page atomicity rule in services.instructions.md. Verification: ruff clean, 381 tests passing, ty unchanged at 10 known SQLAlchemy descriptor false positives. Co-authored-by: Copilot App <[email protected]>
This commit is contained in:
co-authored by
Copilot App
parent
8d3c60fce1
commit
de18c2e9da
@@ -120,6 +120,19 @@ Atomicity rules:
|
||||
- Terminal state (`TRANSCRIBED` or `FAILED`) and transcript row changes must succeed or roll back together.
|
||||
- Retry persistence (`QUEUED` + retry increment + error detail) must succeed or roll back together.
|
||||
|
||||
### Multi-page batches
|
||||
|
||||
These two requirements are in tension for multi-page jobs: each page should be durable as
|
||||
soon as its provider call returns, but the last page must commit together with the terminal
|
||||
status. `process_queued_job` resolves it by committing every page except the last one
|
||||
individually, then deferring the final page's write into `_finalize_batch_outcome` so it
|
||||
shares the terminal transaction.
|
||||
|
||||
Both paths are shielded against cancellation, so the final page is no less durable than the
|
||||
pages before it. Enforced by `tests/integration/test_pipeline_atomicity.py`; per-page
|
||||
durability is separately enforced by
|
||||
`tests/services/test_workflows_reliability.py::TestWorkflowReliability::test_transcribed_page_is_committed_before_next_provider_call_finishes`.
|
||||
|
||||
## Contract Alignment
|
||||
|
||||
- Treat `docs/` as the active architecture and requirements baseline.
|
||||
|
||||
Reference in New Issue
Block a user