retry makes too few attempts and hides the error
Done- Plan (done)
- Code (done)
- Test (done)
- Review (done)
- Finish (done)
Cost
$0.0034
Tests
Passed
Iterations
1
Re-plans
0
LLM calls
11
Prompt read from cache
83%
Usage by agent
- Cache read
- Cache write
- Input
- Output
View as table
| Agent | Cost | Cache read | Cache write | Input | Output |
|---|---|---|---|---|---|
| planner | $0.0009 | 5,636 | 709 | 8 | 1,506 |
| coder | $0.0014 | 18,374 | 3,068 | 12 | 1,745 |
| tester | $0.0011 | 11,690 | 3,525 | 8 | 1,065 |
Timeline
-
planner iteration 1 Finished 3 calls · 7,859 tokens · $0.0009 · 11.3s
Loading…
-
coder iteration 1 Finished 5 calls · 23.2K tokens · $0.0014 · 11.4s
Loading…
-
tester iteration 1 Finished 3 calls · 16.3K tokens · $0.0011 · 7.9s
Loading…
-
verify iteration 1 Passed 0.5s
....... [100%] 7 passed in 0.02s
Final diff
diff --git a/retrying.py b/retrying.py index a49ffae..fbb3bcd 100644 --- a/retrying.py +++ b/retrying.py @@ -1,7 +1,10 @@ def retry(fn, attempts: int = 3): - for _ in range(attempts - 1): + if attempts < 1: + raise ValueError('attempts must be >= 1') + last_exc = None + for _ in range(attempts): try: return fn() - except Exception: - pass - return None + except Exception as exc: + last_exc = exc + raise last_exc diff --git a/test_retrying.py b/test_retrying.py index 409b641..f752226 100644 --- a/test_retrying.py +++ b/test_retrying.py @@ -1,5 +1,71 @@ from retrying import retry +import pytest + + def test_success_first_time(): assert retry(lambda: 5) == 5 + + +def test_succeeds_on_last_attempt(): + calls = [] + + def fn(): + calls.append(1) + if len(calls) < 3: + raise RuntimeError('boom') + return 'ok' + + assert retry(fn, attempts=3) == 'ok' + assert len(calls) == 3 + + +def test_stops_calling_after_first_success(): + calls = [] + + def fn(): + calls.append(1) + if len(calls) < 2: + raise RuntimeError('boom') + return 'ok' + + assert retry(fn, attempts=5) == 'ok' + assert len(calls) == 2 + + +def test_always_failing_calls_attempts_times_and_reraises_last(): + calls = [] + + def fn(): + calls.append(1) + raise ValueError(f'failure {len(calls)}') + + with pytest.raises(ValueError, match='^failure 3$'): + retry(fn, attempts=3) + assert len(calls) == 3 + + +def test_attempts_one_calls_once_and_raises(): + calls = [] + + def fn(): + calls.append(1) + raise KeyError('nope') + + with pytest.raises(KeyError): + retry(fn, attempts=1) + assert len(calls) == 1 + + +@pytest.mark.parametrize('attempts', [0, -1]) +def test_attempts_less_than_one_raises_value_error(attempts): + calls = [] + + def fn(): + calls.append(1) + return 1 + + with pytest.raises(ValueError): + retry(fn, attempts=attempts) + assert calls == []