Repository navigation
Exit 5 when nothing was obtained, no false complete runs, safer outputs and solves - #8
Merged
Merged
Conversation
…and solves - A run with no rows exits 4 only when the site itself said the category is empty or exhausted; every other zero-row ending (page or API never answered, no catalogue form, off-site form, a served page that parsed to nothing) is exit 5. The suite's pinned "never loaded exits 4" check is rewritten to say why. - A page inside the category's own total that yields no rows stops the run as parser_found_nothing / page_not_painted (exit 6 with rows, 5 without) in catalog_client, all three browser engines and the Scraper API client, instead of listing_exhausted/complete. An API that refuses with a refusal status on every attempt is a block (exit 3). - Outputs get the umask's mode (existing files keep theirs), CSV formula cells are neutralised with csv_cells_escaped in the sidecar. - One paid solve per page across every retry and exit, in every engine. - Credential scan judges paths inside the repo, reads .env* backups and fails if it scanned nothing. - Scraper API: waitFor object, http_code status, redacted x-debug. - position counts emitted API rows; category page retried; catalog_client refuses --proxy-rotate per-page; goto status reaches the classifier. - --url help and bug template describe lg.com; private section references removed and guarded; canary red on exit 3/5; two new urllib3 1.x advisories in the pyppeteer lock documented (no compatible pin). Co-Authored-By: Claude Opus 5.5 <[email protected]>
jehrr
marked this pull request as ready for review
October 15, 2026 13:03
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.
Fixes from the 2026-10-14 audit (base
29532be, = v0.2.3).Problem
modelName, an unpainted or unparsed page in a browser engine) ended the run complete, exit 0.venv/orcaptures/; Scraper API sentwaitForas a string, read the verdict string as the status, loggedx-debugwith a CDP password; private section references in shipped files and the v0.2.3 release notes; another site's URLs in--urlhelp and the bug template.Behaviour now
parse_failedpage state (API page empty whereexpected_records(total, page) > 0) andzero_rows_reason()->parser_found_nothing/page_not_painted; the page goes intopages_failed. Same in Playwright (incl. the concurrent path), pyppeteer, Selenium and the Scraper API client. Catalogue API refusing with 401/403/429/503 on every attempt -> exit 3.0o666 & ~umaskfor new files, existing mode kept. CSV-only formula escaping,csv_cells_escapedmerged under the run's own sidecar keys.page_flow.SolveBudget(1 per page) created before the block-retry loop and checked beforesolve()in all three engines; not reset by rotation.ci_checks.py: exclusions onpath.relative_to(REPO).parts,.env*backups scanned, 0 files scanned = failure.waitForobject, status fromhttp_code(intstatusfallback),x-debugredacted (URL credentials,key=, JSON secret fields).positioncounts emitted rows; category GET retried--retriestimes;catalog_client.py --proxy-rotate per-pageis a usage error (it was a silent no-op); Playwright/pyppeteer passgoto()'s status toclassify(cleared after a solve+reload).::error::(this path needs no secret and served bare runners every day); exit 3 no longer passes as a notice.urllib3>=1.25.8,<2.0.0, so no compatible pin exists. README updated (seven advisories).Evidence
smoke_test.py577 passed, 0 failed, 8 skipped. Selenium venv: 588/0/7. pyppeteer venv: 588/0/7. Playwright venv (no browser download): 606 passed, 2 failed — both incheck_fingerprint_refusal_is_an_api_error, which launches Chromium and fails locally only because no browser is installed; CI's engine job installs one.PYTHONDONTWRITEBYTECODE=1,__pycache__cleared), each red on its named check and green after restore: exit-5 rule, parse_failed state, Playwrightor not productsfold, chmod removed, CSV escape off, Selenium budget bypassed (first version of that check stayed green againstif False and not budget.spend(); rewritten as an AST check), absolute-path exclusion,.env.baknot scanned, waitFor string, x-debug verbatim, http_code ignored, citation planted, position by slot, dropped records -> complete, API 403 not a block, per-page accepted.scrape(): page 2 unpainted -> exit 6page_not_painted; page 2 content/0 parsed -> exit 6parser_found_nothing; page 2 exhausted -> exit 0 complete; page 1 parsed nothing / load failed -> exit 5.catalog_client-> 48 rows, complete, exit 0 (no false parse failure on the real last page). One free live run (--pages 10, 2026-10-15): 48 products, 4 pages, complete,csv_cells_escaped: 0, files 0664 under umask 002.Not changed
[Unreleased]).--solve-captcha alwayson a page that is not blocked still buys a token and leaves it in the page's own field (explicit opt-in; unchanged).Metadata/releases (outside the diff): v0.2.3 release notes had two "template §NN" citations removed, rest byte-identical; topics: removed
price-monitoring(the dataset has no prices), addedproduct-catalogandscraping-browser.🤖 Generated with Claude Code