diff --git a/output_writer.py b/output_writer.py index 352b93b..7082f8f 100644 --- a/output_writer.py +++ b/output_writer.py @@ -516,7 +516,7 @@ def finish_run(rows: Sequence[Any], out_prefix: str, fmt: str, # EXIT_NO_PRODUCTS. if blocked: return EXIT_BLOCKED - if stop_reason in FETCH_FAILURE_STOP_REASONS: + if not complete: print(f"[!] The page was never fetched ({stop_reason}) — this is " f"exit {EXIT_FETCH_FAILED}, NOT an empty result " f"(exit {EXIT_NO_PRODUCTS}). Nothing can be concluded about " diff --git a/smoke_test.py b/smoke_test.py index 50c91dc..40a12cf 100644 --- a/smoke_test.py +++ b/smoke_test.py @@ -1021,10 +1021,15 @@ def test_writers(): (dict(blocked=False, stop_reason="page_load_timeout", rows=[]), EXIT_FETCH_FAILED, None), # A named challenge still outranks a transport failure: it says more. (dict(blocked=True, stop_reason="page_load_timeout", rows=[]), EXIT_BLOCKED, None), - # And the negative half, which is what keeps the set honest: - # pages_unattempted means page 1 WAS fetched, so a run holding - # nothing under it really did find nothing. - (dict(blocked=False, stop_reason="pages_unattempted", rows=[]), EXIT_NO_PRODUCTS, None), + # pages_unattempted is a should-never-happen guard: page 1 was + # fetched and the queue never drained. It used to be pinned here at + # exit 4 on the reasoning that the page WAS fetched, so zero rows + # meant an empty listing — and that reasoning was retracted when the + # family unified on `not complete` rather than on a list of stop + # reasons. A list cannot cover a reason nobody has added to it, so + # the list was the hole; and for a state nobody can explain, + # "nothing can be concluded" beats "the listing was empty". + (dict(blocked=False, stop_reason="pages_unattempted", rows=[]), EXIT_FETCH_FAILED, None), ] for i, (kw, expected_rc, expected_status) in enumerate(cases): prefix = os.path.join(tmp, "run%d" % i)