fix(orchestrator): record failed stage in state.json when a handler raises - #11
wangzhengzhuo05 wants to merge 1 commit into
Conversation
|
Closing this out. It has been waiting 7 days without any maintainer review, and we are winding down this contribution effort — a stale PR sitting in the queue costs maintainers attention without giving them a decision to make, so it is better closed than left open indefinitely. If the direction is useful, the branch is intact on the fork ( What it contains: fix(orchestrator): record failed stage in state.json when a handler raises — It was verified locally before opening (target test suite green, plus a mutation check that reverts only the fix and confirms the new regression test fails). Thanks for the time. |
What
Orchestrator.run_stagenow records a failed stage instate.jsonbefore re-raising, so a handler crash duringrecon/test/reportno longer leaves the workspace with stage artifacts on disk but no record of what happened.Why
Fixes #10. As reported, when a stage handler raised,
run_stageexited before_save_state, so:completed_stagesstayed empty andhistorynever saw the attempt;cmd_run) got an exception and then aload_state()that printed nothing useful.How
src/cain_agent/orchestrator.py— wrap the handler call intry / except Exception; on failure persistcurrent_stage, the unchangedcompleted_stages,updated_at,history(with a{"status": "failed", "error": "..."}entry) plusfailed_stageanderror, then re-raisethe original exception unchanged.run_stagerewrites the state dict, sofailed_stage/errorclear themselves — that is the recovery path covered by test 3.run()needed no change; it inherits the recording becauserun_stagere-raises.Tests
.venv/bin/python -m pytest tests/test_orchestrator.py -q→ 14 passed.venv/bin/python -m pytest -q→ 1118 passed, 3 skippedruff checkon both changed files → cleanThree new tests:
test_failed_stage_is_recorded_in_state— record present,completed_stagesempty, history has thefailedentry,state.jsonon disk.test_run_records_state_when_a_handler_raises— therun()path persists the failure too.test_failure_marker_is_cleared_after_a_successful_stage— a successful retry dropsfailed_stage.Mutation check
Reverted only the fix's behaviour (
except Exception→except ZeroDivisionError) with the new tests left in place:Restored → 14 passed. The tests fail for the intended reason, so they guard the new behaviour instead of passing vacuously.
AI disclosure
This change was implemented with AI assistance (OpenCode + muse-spark 1.3) and reviewed, tested, and mutation-checked by the submitter.
Fixes #10