fix: fail the run when an archive is refused or will not open - #634
Open
Nitjsefnie wants to merge 1 commit into
Open
fix: fail the run when an archive is refused or will not open#634Nitjsefnie wants to merge 1 commit into
Nitjsefnie wants to merge 1 commit into
Conversation
`extract_archive` refuses an oversized expansion (AgoraDMV#279) and a too-large member count (AgoraDMV#306) by raising, and both comments describe that as failing loud. The caller undid it: `extract_archives` logged `Failed <archive>` and continued, the parse phase found no folder and indexed zero bills for that congress and bill type -- a status line indistinguishable from one that legitimately had nothing new -- and the process exited 0. An unattended run reported success over a corpus missing every bill the archive held, which is the outcome both ceilings exist to prevent (AgoraDMV#325). Counted and reported at the end, rather than propagated on the spot, because the broad `except` buys batch resilience worth keeping: one bad archive must not cost the healthy ones. That is the direction this repository already took for a skipped CSV row in `fetch_bills.py download-all`, which completes every remaining row and then exits 1. - `extract_archives` attempts every archive and then raises `ArchivesNotExtracted`, naming all of them. It covers both ceilings and an archive that will not open at all: the corpus is missing those bills either way, and the likeliest real failure is the one a ceiling-only rule would miss. - `fetch_bill_archives` holds that failure across phase 3 and re-raises it after, so everything that did extract still reaches the index. - A `main` maps it to exit 1 with a one-liner instead of a traceback: the fault is in the data or in a ceiling, not in this script. An archive skipped because its folder already exists is not a failure -- that is the cache working, and counting it would make every re-run of a healthy corpus exit nonzero. The new tests are two-sided throughout: asserting only the status would be satisfied by aborting the batch on the first refusal, so each one pins that the healthy archives still extract, and the end-to-end case pins that they still reach the index. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related issue
Closes #325
Also filed while doing this work, not fixed here:
What does this change?
An archive refused by an extraction ceiling, or one that will not open, is no longer dropped from the corpus in silence — the run now completes every archive and then exits nonzero.
Option 2 from the issue, not option 1. The batch still runs to completion, so every archive that did extract still reaches the index; the failure is reported afterwards. Option 3 was considered and rejected on evidence: the download path already
.part-stages and calls_verify_archive_complete, so "a corrupt ZIP is expected debris to skip" does not hold in this repo.The reviewable decision is that
extract_archivesnow raisesArchivesNotExtractedafter the loop rather than returning a shorter list.extract_archiveshas exactly one production caller, so this costs no external contract, and a raise is the one shape a caller cannot accidentally ignore — which is the whole of #325. It reuses the existingCongressNotAvailable→main→sys.exit(1)mechanism (tools/fetch_bills.py:833-837) to carry the policy fromf180c36, where the CSV path exits nonzero on skipped rows.Both ceilings are covered, not only the newer one: the member-count ceiling at
tools/fetch_bill_archives.py:265and the byte ceiling at:269, with a test for each.How to test
The behaviour is pinned by
tests/test_fetch_bill_archives_run_status.py, which builds ZIPs intmp_path— no network, no fixtures.Each test asserts both halves, and that is deliberate: asserting only the nonzero exit would also pass an implementation that aborts on the first failure and throws away the rest of the batch, which is the cost the issue names for option 1.
Run it both ways, as the checklist asks:
That second pair is what shows the tests distinguish "report after completing the batch" from "abort on first failure", rather than merely detecting that something changed.
I have not ticked "ran the CI gates locally": the full suite was run on a GitHub runner rather than on my machine, across all 25 jobs, and locally I ran only the touched test files. Two pre-existing entrypoint tests fail before this change with
AttributeErrorrather than an assertion; they are not part of the evidence above.Checklist
Closes #...)AI assistance
Generated by Claude Opus 5 (brief, implementation, review, testing)