fix(cli): a WAF-blocked Kanban worker exits KANBAN_TERMINAL_PROVIDER_EXIT_CODE, not 1
upstream_blocked was in neither provider-reason set, so a worker hitting a User-Agent firewall exited 1 and the dispatcher re-spawned it into the same wall until kanban.failure_limit was spent (on base the same 403 classified auth and parked the card after one spawn). A header change heals it, a retry never does: it is terminal.
This commit is contained in:
4
cli.py
4
cli.py
@@ -4137,8 +4137,10 @@ _TRANSIENT_PROVIDER_REASONS = frozenset({
|
||||
# ``KANBAN_TERMINAL_PROVIDER_EXIT_CODE`` so the dispatcher parks the card after ONE spawn with
|
||||
# the provider's words as the reason, instead of re-spawning into the same wall until
|
||||
# ``kanban.failure_limit`` is spent. ``billing`` stays transient: credit comes back.
|
||||
# ``upstream_blocked`` (a WAF/CDN refusing the SDK's User-Agent) is terminal too: only a
|
||||
# header change heals it, never a retry.
|
||||
_TERMINAL_PROVIDER_REASONS = frozenset({
|
||||
"auth", "auth_permanent", "model_not_found", "ssl_cert_verification",
|
||||
"auth", "auth_permanent", "model_not_found", "ssl_cert_verification", "upstream_blocked",
|
||||
})
|
||||
|
||||
|
||||
|
||||
@@ -53,16 +53,27 @@ def test_dispatcher_spawned_worker_signals_a_provider_outage_not_a_protocol_viol
|
||||
assert code == KANBAN_RATE_LIMIT_EXIT_CODE
|
||||
|
||||
|
||||
@pytest.mark.parametrize("reason", ["auth", "auth_permanent", "model_not_found", "ssl_cert_verification"])
|
||||
@pytest.mark.parametrize(
|
||||
"reason", ["auth", "auth_permanent", "model_not_found", "ssl_cert_verification", "upstream_blocked"]
|
||||
)
|
||||
def test_dispatcher_spawned_worker_signals_a_terminal_provider_error(monkeypatch, reason):
|
||||
"""A revoked credential / missing model cannot be retried into working: the worker says so
|
||||
with EX_CONFIG so the dispatcher parks the card after one spawn. A person's run keeps 1."""
|
||||
"""A revoked credential / missing model / WAF User-Agent block cannot be retried into working:
|
||||
the worker says so with EX_CONFIG so the dispatcher parks the card after one spawn. A person's
|
||||
run keeps 1."""
|
||||
monkeypatch.setenv("HERMES_KANBAN_TASK", "t_abc123")
|
||||
assert _run_non_quiet(monkeypatch, {"failed": True, "failure_reason": reason}) == KANBAN_TERMINAL_PROVIDER_EXIT_CODE
|
||||
monkeypatch.delenv("HERMES_KANBAN_TASK")
|
||||
assert _run_non_quiet(monkeypatch, {"failed": True, "failure_reason": reason}) == 1
|
||||
|
||||
|
||||
def test_dispatcher_spawned_worker_keeps_a_plain_failure_at_one(monkeypatch):
|
||||
"""Control: a task-level failure (or an unknown reason) is neither transient nor terminal —
|
||||
the worker exits 1 and the dispatcher counts it against ``kanban.failure_limit`` as before."""
|
||||
monkeypatch.setenv("HERMES_KANBAN_TASK", "t_abc123")
|
||||
assert _run_non_quiet(monkeypatch, {"failed": True, "failure_reason": "some_unknown_reason"}) == 1
|
||||
assert _run_non_quiet(monkeypatch, {"failed": True}) == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("turn_result", "expected"),
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user