fix(sleep): reset ClaudeCliBackend.last_call_error at each call start

Follow-up to #126. ClaudeCliBackend recorded last_call_error on failure but
never reset it, so a failure followed by a successful call still reported the
stale error in persisted diagnostics — making a healthy run look failed. Both
_call() and attempt_with_tools() now clear it at the start, matching
CodexCliBackend.

Note: the "TimeoutExpired leaks the prompt into logs" concern raised in review
does NOT apply on current main — the prompt is passed via stdin (input=), not
argv (fixed by #98), so TimeoutExpired's str() only contains the argv (no
prompt). Verified empirically.

Adds a regression test asserting a prior failure is cleared on the next
success.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Yif Yang
2026-07-12 16:33:18 +00:00
parent 49a5b617c0
commit fad8fdb01f
2 changed files with 24 additions and 0 deletions
+20
View File
@@ -1148,6 +1148,26 @@ class TestClaudeCliBackendBare(unittest.TestCase):
self.assertEqual(resp, "")
self.assertIn("Claude CLI spawn failed", be.last_call_error)
def test_last_call_error_cleared_on_next_success(self):
"""A prior failure must not make a later successful call look failed:
_call resets last_call_error at the start of each call."""
from unittest import mock
from skillopt_sleep.backend import ClaudeCliBackend
be = ClaudeCliBackend(claude_path="claude", timeout=3)
# First call fails to spawn -> error recorded.
with mock.patch("skillopt_sleep.backend.subprocess.run",
side_effect=FileNotFoundError("no claude")):
self.assertEqual(be._call("p1"), "")
self.assertIn("Claude CLI spawn failed", be.last_call_error)
# Next call succeeds -> stale error must be cleared.
class _OK:
stdout = "answer"
stderr = ""
with mock.patch("skillopt_sleep.backend.subprocess.run", return_value=_OK()):
self.assertEqual(be._call("p2"), "answer")
self.assertEqual(be.last_call_error, "")