Skip to content

Commit e9a4871

Browse files
committed
fix(workflows): address Copilot review feedback on continue_on_error
- Reword README "Error Handling" intro in terms of `StepStatus.FAILED` halting by default, with non-zero shell/command exit as one common cause. Avoids implying only exit codes can halt a run (gate aborts and validation failures also do, just via different mechanisms). - Tighten `test_validation_accepts_bool_continue_on_error` to assert `errors == []` instead of "no error mentions continue_on_error", so unrelated validation regressions on the same minimal YAML can no longer slip past this test. - In `test_gate_abort_still_halts_with_continue_on_error`, swap `sys.stdin` itself for a stub `_TTYStdin` instead of patching `sys.stdin.isatty`. Method-on-instance assignment is unreliable on real `io.TextIOWrapper` objects (e.g. under pytest with capture disabled), so replacing the whole stdin object is more robust across runners. All 2967 tests still pass.
1 parent da8ed4d commit e9a4871

2 files changed

Lines changed: 17 additions & 9 deletions

File tree

tests/test_workflows.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2058,7 +2058,14 @@ def test_gate_abort_still_halts_with_continue_on_error(
20582058
# Force the gate step into interactive mode and feed a "reject"
20592059
# choice so the abort path actually runs in the test env
20602060
# (default behaviour returns PAUSED when stdin is not a TTY).
2061-
monkeypatch.setattr(gate_module.sys.stdin, "isatty", lambda: True)
2061+
# Swap sys.stdin itself for a stub: setattr on the real
2062+
# TextIOWrapper's `isatty` method is not assignable under some
2063+
# runners (e.g. pytest with capture disabled).
2064+
class _TTYStdin:
2065+
def isatty(self) -> bool:
2066+
return True
2067+
2068+
monkeypatch.setattr(gate_module.sys, "stdin", _TTYStdin())
20622069
monkeypatch.setattr(
20632070
GateStep, "_prompt", staticmethod(lambda _msg, _opts: "reject")
20642071
)
@@ -2135,9 +2142,7 @@ def test_validation_accepts_bool_continue_on_error(self):
21352142
continue_on_error: {yaml_value}
21362143
""")
21372144
errors = validate_workflow(definition)
2138-
assert not any(
2139-
"continue_on_error" in e for e in errors
2140-
), errors
2145+
assert errors == [], errors
21412146

21422147

21432148
# ===== State Persistence Tests =====

workflows/README.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -221,11 +221,14 @@ Aggregate results from fan-out steps:
221221

222222
## Error Handling
223223

224-
By default, a non-zero exit code from any step halts the entire run.
225-
Set `continue_on_error: true` on a step to record its result and
226-
continue to the next sibling step instead. The exit code remains
227-
available on `steps.<id>.output.exit_code` so downstream `if`,
228-
`switch`, or `gate` steps can branch on it:
224+
By default, any step that ends in `StepStatus.FAILED` halts the entire
225+
run — most commonly a `shell` or `command` step exiting non-zero, but
226+
also things like a step type that fails validation. Set
227+
`continue_on_error: true` on a step to record its result and continue
228+
to the next sibling step instead. When the failure was a non-zero
229+
exit, the exit code remains available on
230+
`steps.<id>.output.exit_code` so downstream `if`, `switch`, or `gate`
231+
steps can branch on it:
229232

230233
```yaml
231234
- id: heavy-thing

0 commit comments

Comments
 (0)