Repository navigation
Stop no-proxy crashes, cap paid solves per page, exit 5 when a page is not obtained - #14
Merged
Merged
Conversation
…ge is not obtained - pyppeteer and Selenium no longer raise AttributeError (exit 1) on the first blocked page or failed navigation without --proxy; they re-fetch through the same access path like Playwright. - Both captcha call sites in every engine claim from one per-page solve allowance immediately before purchase; retries and rotations do not reset it. - Playwright and pyppeteer pass the navigation's HTTP status to the classifier; 404/410 are not read as a block. - A served page that never painted, or whose tiles parse to zero rows, is page_never_painted / parser_found_nothing: exit 5 (6 with rows), not 4. - Negative/zero counting and delay flags are usage errors naming the flag, in every engine and the Scraper API client. - Credential scan excludes paths relative to the repo and fails on 0 files. - --allow-empty writes a "complete" sidecar for a completed empty run. - Canary fails when TOKOPEDIA_CDP_ENDPOINT is missing and on exit 3/5/6. - .gitignore covers --dump-html page files and capture directories. - Remove private-instruction citations, stale shop-mode text and the credential-lasts-a-day claim; offline guards for each change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jehrr
marked this pull request as ready for review
October 15, 2026 22:21
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.
Problem
An audit of
mainatfa8b613reproduced these defects with driver-free probes:--proxy, pyppeteer (on a blocked page or a failed navigation) and Selenium (on a blocked page) calledpool.current/pool.advanceonNone. The result was anAttributeErrorand exit 1 where exit 3 or 5 was due.SOLVES_PER_PAGE = 1in Playwright. pyppeteer and Selenium bought 2 and then crashed (see above).status != 200branch could never run.unknown), and a page holding tiles that parsed to zero rows.venv, the scan read 0 files and still printed "ok".--pages,--delay,--concurrency,--retry-delayand--proxy-block-retriesvalues, and the Scraper API client's--retries,--retry-delayand--timeout, were accepted;--allow-emptywrote a"failed"sidecar for a completed empty run;.gitignoredid not coverX.pageNdumps or capture directories;--mode shop;Resulting behaviour
page_flow.SolveBudgetis shared by both call sites in all three engines and is claimed immediately before the paid request. Detecting nothing, finding content already rendered or having no key claims nothing. A retry or a rotation does not reset it.goto()response and pass its status to the classifier, so 403, 429 and 5xx mean blocked (exit 3). Selenium has no status and passesstatus=NO_HTTP_STATUSat each call. 404 and 410 are deliberately not read as a block: what Tokopedia sends for a dead URL has not been measured.page_never_painted, and a content page with zero parsed rows asparser_found_nothing. Both exit 5, or 6 when earlier pages gave rows. A real empty page (no-results text, hub, past the end) is still exit 4.--allow-empty. A completed empty run gets a"complete"sidecar withproducts: 0.TOKOPEDIA_CDP_ENDPOINTsecret the job fails with an::error::that names the secret. Only exit 0 passes, and the data checks (row floor, non-null core fields) then run. It is still dispatch-only; a schedule is to be added once the secret exists.Evidence
Core-only venv.
PYTHONDONTWRITEBYTECODE=1 python smoke_test.pygivessmoke_test: OK, 537 PASS, 0 FAIL. The 4 engine groups are skipped by name, as before.Engine venvs. Each venv installs
requirements.txtplus one engine file, with no browser download:In each venv that engine's group ran. The new fetch-loop probe imported the real driver there and a stub driver module elsewhere.
CLI checks. In each engine venv,
--pages -1,--delay -2,--concurrency 0,--proxy-block-retries -1and--retry-delay -1give exit 2 withargument --<flag>: …. Inscraper_api_client.py, the same holds for--retries -1,--timeout 0and--retry-delay -1.Driven checks. New suite checks run each engine's real
_fetch_one_pageagainst a fake session:gotoreaches the classifier and the page is blocked (Playwright and pyppeteer);unknowngivespage_never_painted,contentwith 0 rows givesparser_found_nothing, andemptystays ok.Controls. Each fault was planted, the suite went red on the named check, the file was restored, and the suite went green again:
not_obtained_reasonreturning None;--pages type=int, Scraper API--retries type=int;--allow-emptywriting"failed".No paid calls, proxies, credentials or live requests to Tokopedia were made. The site refuses datacentre addresses.
Not changed
TOKOPEDIA_CDP_ENDPOINTsecret exists, because a daily run would be red for a known reason. This is the owner's decision.--concurrencywith--cdp-endpointor on the mirror engines. Still warned and ignored; this is an owner decision.not_foundstate. A dead product URL now ends as exit 5 rather than 4. A separate state needs a live measurement first.[Unreleased]now holds the--retries 0change and the changes above..jsonor.env*backups, and the audit did not flag that.🤖 Generated with Claude Code