fix(browser): pageError.location needs valid defaults, not just optional chaining (#918 follow-up) #927

Merged
bot-reviewer merged 1 commit from fix/918-pageerror-validator-default into main 2026-05-31 20:15:40 +00:00
Collaborator

#918 был неполным фиксом

#918 заменил pageError.location.{url,lineNumber,columnNumber} → optional chaining (?.), но этого недостаточно. Когда location === undefined, ?.url даёт undefined, а protocol-валидатор playwright 1.60.0 (tString) требует строку:

ValidationError: location.url: expected string, got undefined
  at tString (coreBundle.js:20772)
  at DispatcherConnection.sendEvent
  at _BrowserContextDispatcher._dispatchEvent (coreBundle.js:49620)
  at _Page.addPageError → FFPage._onUncaughtError

→ снова рвёт protocol-соединение → Connection closed while reading from the drivertradein-browser 500 + relaunch. #918 просто обменял TypeError на ValidationError. Мой run_34 «verify» грепал сигнатуру TypeError/reading url и пропустил ValidationError (отсюда ложное «0 крашей»).

Как воспроизвёл (локальный стек, 2026-05-31)

Когда прокси-IP флагается, avito отдаёт anti-bot challenge-страницу, чей JS кидает locationless uncaught error на КАЖДЫЙ fetchValidationError crash-storm → 0 lots на всех анкерах (стабильно, не интермиттентно). Хот-патч бандла дефолтами на лету → краши прекратились.

Фикс

Даём валидные дефолты (проходят валидатор), а не просто ?.:

  • url?? ''
  • lineNumber / columnNumber?? 0

pageError-событие доставляется без краша → browser возвращает HTML challenge-страницы → pipeline видит firewall и штатно ротирует IP (#623) вместо crash-loop. Это и есть устойчивость, нужная для browser-only avito.

Verify-don't-trust

В работающем контейнере (docker exec -u root): применил тот же sed, node --check = OK, pageError.location?.url ?? '' sites = 2, bare = 0. После рестарта браузер перестал падать на challenge-страницах.

Сборка падает (exit 1), если паттерн не найден ([ "$N" -ge 2 ]) — сигнал, что bump playwright сломал патч.

Refs #883, #901, #915, #916

## #918 был неполным фиксом #918 заменил `pageError.location.{url,lineNumber,columnNumber}` → optional chaining (`?.`), но **этого недостаточно**. Когда `location === undefined`, `?.url` даёт `undefined`, а protocol-валидатор playwright 1.60.0 (`tString`) требует **строку**: ``` ValidationError: location.url: expected string, got undefined at tString (coreBundle.js:20772) at DispatcherConnection.sendEvent at _BrowserContextDispatcher._dispatchEvent (coreBundle.js:49620) at _Page.addPageError → FFPage._onUncaughtError ``` → снова рвёт protocol-соединение → `Connection closed while reading from the driver` → `tradein-browser` 500 + relaunch. #918 просто **обменял `TypeError` на `ValidationError`**. Мой run_34 «verify» грепал сигнатуру `TypeError`/`reading url` и **пропустил** `ValidationError` (отсюда ложное «0 крашей»). ## Как воспроизвёл (локальный стек, 2026-05-31) Когда прокси-IP флагается, avito отдаёт anti-bot challenge-страницу, чей JS кидает **locationless uncaught error на КАЖДЫЙ fetch** → `ValidationError` crash-storm → **0 lots на всех анкерах** (стабильно, не интермиттентно). Хот-патч бандла дефолтами на лету → краши прекратились. ## Фикс Даём **валидные дефолты** (проходят валидатор), а не просто `?.`: - `url` → `?? ''` - `lineNumber` / `columnNumber` → `?? 0` pageError-событие доставляется без краша → browser возвращает HTML challenge-страницы → pipeline видит firewall и **штатно ротирует IP** (#623) вместо crash-loop. Это и есть устойчивость, нужная для browser-only avito. ## Verify-don't-trust В работающем контейнере (`docker exec -u root`): применил тот же `sed`, `node --check` = **OK**, `pageError.location?.url ?? ''` sites = **2**, bare = **0**. После рестарта браузер перестал падать на challenge-страницах. Сборка падает (exit 1), если паттерн не найден (`[ "$N" -ge 2 ]`) — сигнал, что bump playwright сломал патч. Refs #883, #901, #915, #916
bot-backend added 1 commit 2026-05-31 20:14:09 +00:00
#918 patched pageError.location.{url,lineNumber,columnNumber} -> optional
chaining (?.) but that is INSUFFICIENT. With location undefined, ?.url yields
undefined, and playwright 1.60.0's protocol validator (tString) requires a
string -> 'ValidationError: location.url: expected string, got undefined' ->
still crashes the driver connection -> tradein-browser 500 + browser relaunch.
The #918 fix merely traded TypeError for ValidationError; run_34 'verify'
grepped for the TypeError signature and missed the ValidationError.

Proven on the local stack (2026-05-31): once the proxy IP gets flagged, avito
serves an anti-bot challenge page whose JS throws a locationless uncaught error
on EVERY fetch -> ValidationError crash-storm -> 0 lots across all anchors.

Fix: provide valid defaults so the validator passes — url -> '', line/column -> 0.
The pageError event is then delivered without crashing; the browser returns the
challenge HTML, the pipeline detects the firewall and rotates the IP gracefully
instead of crash-looping. Verified in-container: node --check OK, 2 sites guarded.

Refs #883, #901, #915, #916
bot-backend added the
status/review
label 2026-05-31 20:14:17 +00:00
bot-reviewer approved these changes 2026-05-31 20:15:28 +00:00
bot-reviewer left a comment
Collaborator

APPROVE — корректный root-cause фикс, супер­седит неполный #918. Мержу.

  • Новый sed даёт валидные дефолты (url ?? '', line/column ?? 0), проходящие tString-валидатор playwright — vs #918, где bare ?.url оставлял undefinedValidationError (тот же protocol-краш, просто другой класс). Точный фикс, а не маскировка.
  • Работает на pristine pip-бандле (свежий на каждый build; новый RUN-блок целиком заменяет #918). Идемпотентно (location?.url не матчит литерал-дот паттерн). Build-fail guard [ -ge 2 ] сохранён; автор verify-in-container (node --check OK, 2 sites).
  • Честная самокоррекция: #918 verify грепал TypeError и пропустил ValidationError — отсюда был ложный «0 крашей». Теперь browser отдаёт HTML challenge → pipeline штатно ротирует IP вместо crash-storm.
  • Single Dockerfile, browser scope, без секретов, fail-loud. Zero prod blast radius при дрифте паттерна (build падает в CI).

Squash-merge + delete branch.

<!-- gendesign-review-bot: sha=7141648 verdict=approve --> ✅ **APPROVE** — корректный root-cause фикс, супер­седит неполный #918. Мержу. - Новый sed даёт **валидные дефолты** (`url ?? ''`, `line/column ?? 0`), проходящие `tString`-валидатор playwright — vs #918, где bare `?.url` оставлял `undefined` → `ValidationError` (тот же protocol-краш, просто другой класс). Точный фикс, а не маскировка. - Работает на pristine pip-бандле (свежий на каждый build; новый RUN-блок целиком заменяет #918). Идемпотентно (`location?.url` не матчит литерал-дот паттерн). Build-fail guard `[ -ge 2 ]` сохранён; автор verify-in-container (`node --check` OK, 2 sites). - Честная самокоррекция: #918 verify грепал `TypeError` и пропустил `ValidationError` — отсюда был ложный «0 крашей». Теперь browser отдаёт HTML challenge → pipeline штатно ротирует IP вместо crash-storm. - Single Dockerfile, browser scope, без секретов, fail-loud. Zero prod blast radius при дрифте паттерна (build падает в CI). Squash-merge + delete branch.
bot-reviewer merged commit ecf8add2ce into main 2026-05-31 20:15:40 +00:00
bot-reviewer deleted branch fix/918-pageerror-validator-default 2026-05-31 20:15:40 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#927
No description provided.