refactor(roi): isolate outage validation and verify uncached retry

This commit is contained in:
moe-berri 2026-09-30 11:23:05 -07:00
parent 293be19a7b
commit 8db5733d1c
2 changed files with 17 additions and 9 deletions

View file

@ -245,6 +245,14 @@ class _ProcessedPull(NamedTuple):
metadata_unavailable: bool = False
def _processed_records(processed: tuple[_ProcessedPull, ...]) -> Mapping[int, ROIPullRecord]:
if processed and all(item.metadata_unavailable for item in processed):
raise SourceError(
"GitHub could not provide PR metadata. No new report was published; try analysis again later."
)
return MappingProxyType({item.position: item.record for item in processed})
class SyncManager:
def __init__(
self,
@ -479,13 +487,7 @@ class SyncManager:
if not worker_task.done():
worker_task.cancel()
await asyncio.gather(*workers, return_exceptions=True)
if processed and all(item.metadata_unavailable for item in processed):
raise SourceError(
"GitHub could not provide PR metadata. No new report was published; try analysis again later."
)
processed_by_index: Final[Mapping[int, ROIPullRecord]] = MappingProxyType(
{item.position: item.record for item in processed}
)
processed_by_index: Final = _processed_records(processed)
report: Final = ROIReport(
mode="live",
start=start.isoformat(),

View file

@ -295,12 +295,18 @@ async def test_metadata_outage_keeps_previous_report_and_retries_on_next_run() -
assert manager.status.needs_attention == 1
assert manager.status.error is not None and "No new report was published" in manager.status.error
assert repository.values["roi_calculator_report"] == previous
assert await manager.start(_settings(), repository, _spend_reader(), _completion(), _transport())
assert await manager.start(
_settings(estimator_prompt="New prompt invalidates saved estimates"),
repository,
_spend_reader(),
_completion(),
_transport(),
)
await _wait_until_finished(manager)
recovered: Final = TypeAdapter(ROIReport).validate_python(repository.values["roi_calculator_report"])
assert recovered["pulls"][0]["estimate"]["status"] == "estimated"
assert recovered["pulls"][0]["estimate"]["hours"] == 4
assert manager.status.reused == 1
assert manager.status.reused == 0
@pytest.mark.asyncio