fix(tradein/scraper): диагноз бана перестаёт назначаться по умолчанию (#2764) #2765

Merged
bot-backend merged 1 commit from fix/2764-ban-kind-no-default into main 2026-08-06 23:18:00 +00:00
Collaborator

Что

#2711 развёл «наш сбой» и «блокировка площадкой» полем ban_kind, но дефолт в сигнатуре mark_banned остался platform, а диагноз передавали 3 вызывающих из 13. Замер на проде (2026-08-07): из 133 строк banned две написаны уже в рантайме — и обе получили platform по умолчанию из общего финализатора backfill-задач (#2695/#2674), который диагноз не передаёт вовсе.

Вызывающий Передавал диагноз? Тип исключения известен? После правки
pipeline:1568 city-sweep detail-abort да да без изменений
pipeline:1782 nb-sweep SERP block да да без изменений
pipeline:3644 avito full-load да да без изменений
pipeline:2305/2336 yandex sweep, N подряд нет нет (timeout / broad Exception) unknown
pipeline:2829/2857 cian sweep, N подряд нет нет unknown
pipeline:2374/2890/3189/3419 «все попытки не извлекли структуру» нет исключения нет вовсе (счётчики) unknown
pipeline:3873 domclick QRATOR нет тип неразделим unknown
scrape_runs.mark_backfill_finished (avito) нет да, поштучно диагноз блоков
mark_backfill_finished (domclick) нет тип неразделим unknown (ограничение названо в коде)
mark_backfill_finished (yandex) нет ветка banned недостижима (нет счётчика blocked)

Как

  • дефолт mark_bannedunknown (обе копии runs-модуля): пробел становится измеримым (SELECT ban_kind, count(*)), а platform/infra начинают означать доказанное. Обязательный параметр отвергнут: 9 из 13 вызывающих типа не знают, и они скопировали бы любую строку, которую попросят.
  • ban_kind_of_exception: else PLATFORM был тем же назначенным диагнозом уровнем ниже (тест #2711 прямо утверждал RuntimeError → platform). Теперь третий исход — unknown.
  • fetch_detail browser-режим (п. 3 issue): поднимал AvitoBlockedError на ЛЮБОЙ отказ сайдкара — 503 «browser unavailable», ConnectError/ReadTimeout, пустой пул. Диагноз врал даже там, где передавался. Теперь AvitoSidecarUnavailableError (подтип AvitoRateLimitedError) — все except (AvitoBlockedError, AvitoRateLimitedError) ловят его без изменений, чекпоинт done_buckets сохраняется так же. Зеркало того, что #2686 уже сделал для SERP-ветки.
  • avito_detail_backfill доносит диагнозы своих блоков до финализатора; сошлись — пишется, разошлись — unknown.
  • миграция 234: unknown в CHECK (без неё запись падала бы, а падение внутри задачи выглядело бы обычным failed), COMMENT, и перевод двух строк, помеченных дефолтом ПОСЛЕ применения 218. Ретро-классификация 218 по тексту не тронута.

Test plan

  • 11 проверок падают на старом коде (прогон против origin/main с одной лишь константой-заглушкой): финализатор ×3, browser-ветка detail ×4, классификатор, дефолт обеих копий ×2, проводка backfill'а ×2.
  • Два теста чекпоинта из #2711 (test_full_load_*_keeps_checkpoint) зелёные — путь сохранения done_buckets не тронут.
  • Полный сьют tradein-backend: 3635 passed; 11 падений идентичны прогону origin/main (пробелы локального venv, не эта правка).
  • ruff check / ruff format чисто по изменённым файлам.
  • После деплоя: SELECT ban_kind, count(*) FROM scrape_runs WHERE status='banned' GROUP BY 1 → появление unknown (2 исторические + новые).

Refs #2764

## Что #2711 развёл «наш сбой» и «блокировка площадкой» полем `ban_kind`, но дефолт в сигнатуре `mark_banned` остался `platform`, а диагноз передавали **3 вызывающих из 13**. Замер на проде (2026-08-07): из 133 строк `banned` две написаны уже в рантайме — и обе получили `platform` **по умолчанию** из общего финализатора backfill-задач (#2695/#2674), который диагноз не передаёт вовсе. | Вызывающий | Передавал диагноз? | Тип исключения известен? | После правки | |---|---|---|---| | `pipeline:1568` city-sweep detail-abort | да | да | без изменений | | `pipeline:1782` nb-sweep SERP block | да | да | без изменений | | `pipeline:3644` avito full-load | да | да | без изменений | | `pipeline:2305/2336` yandex sweep, N подряд | нет | нет (timeout / broad `Exception`) | `unknown` | | `pipeline:2829/2857` cian sweep, N подряд | нет | нет | `unknown` | | `pipeline:2374/2890/3189/3419` «все попытки не извлекли структуру» | нет | исключения нет вовсе (счётчики) | `unknown` | | `pipeline:3873` domclick QRATOR | нет | тип неразделим | `unknown` | | `scrape_runs.mark_backfill_finished` (avito) | нет | **да**, поштучно | диагноз блоков | | `mark_backfill_finished` (domclick) | нет | тип неразделим | `unknown` (ограничение названо в коде) | | `mark_backfill_finished` (yandex) | нет | ветка `banned` недостижима (нет счётчика blocked) | — | ## Как - **дефолт `mark_banned` → `unknown`** (обе копии runs-модуля): пробел становится измеримым (`SELECT ban_kind, count(*)`), а `platform`/`infra` начинают означать доказанное. Обязательный параметр отвергнут: 9 из 13 вызывающих типа не знают, и они скопировали бы любую строку, которую попросят. - **`ban_kind_of_exception`**: `else PLATFORM` был тем же назначенным диагнозом уровнем ниже (тест #2711 прямо утверждал `RuntimeError → platform`). Теперь третий исход — `unknown`. - **`fetch_detail` browser-режим** (п. 3 issue): поднимал `AvitoBlockedError` на ЛЮБОЙ отказ сайдкара — 503 «browser unavailable», ConnectError/ReadTimeout, пустой пул. Диагноз врал даже там, где передавался. Теперь `AvitoSidecarUnavailableError` (подтип `AvitoRateLimitedError`) — все `except (AvitoBlockedError, AvitoRateLimitedError)` ловят его без изменений, чекпоинт `done_buckets` сохраняется так же. Зеркало того, что #2686 уже сделал для SERP-ветки. - **`avito_detail_backfill`** доносит диагнозы своих блоков до финализатора; сошлись — пишется, разошлись — `unknown`. - **миграция 234**: `unknown` в CHECK (без неё запись падала бы, а падение внутри задачи выглядело бы обычным `failed`), COMMENT, и перевод двух строк, помеченных дефолтом ПОСЛЕ применения 218. Ретро-классификация 218 по тексту не тронута. ## Test plan - [x] 11 проверок падают на старом коде (прогон против `origin/main` с одной лишь константой-заглушкой): финализатор ×3, browser-ветка detail ×4, классификатор, дефолт обеих копий ×2, проводка backfill'а ×2. - [x] Два теста чекпоинта из #2711 (`test_full_load_*_keeps_checkpoint`) зелёные — путь сохранения `done_buckets` не тронут. - [x] Полный сьют tradein-backend: 3635 passed; 11 падений идентичны прогону `origin/main` (пробелы локального venv, не эта правка). - [x] `ruff check` / `ruff format` чисто по изменённым файлам. - [ ] После деплоя: `SELECT ban_kind, count(*) FROM scrape_runs WHERE status='banned' GROUP BY 1` → появление `unknown` (2 исторические + новые). Refs #2764
bot-backend added 1 commit 2026-08-06 23:12:39 +00:00
fix(tradein/scraper): диагноз бана перестаёт назначаться по умолчанию (#2764)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 7s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI / changes (pull_request) Successful in 8s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 3m42s
47d0afb3dd
#2711 развёл «наш сбой» и «блокировка площадкой» полем ban_kind, но дефолт в
сигнатуре mark_banned остался 'platform', а диагноз передавали 3 вызывающих из
13. На проде обе строки, помеченные уже в рантайме (3306 avito 12:42, 3313
domclick 15:20), получили 'platform' по умолчанию из общего финализатора
backfill-задач: метка выглядела доказательством, не будучи им.

- дефолт mark_banned → 'unknown' (обе копии runs-модуля): пробел становится
  измеримым в данных, а 'platform'/'infra' начинают означать доказанное;
- ban_kind_of_exception: `else PLATFORM` был тем же назначенным диагнозом
  уровнем ниже — теперь тип, который ничего не доказывает, даёт 'unknown';
- fetch_detail в browser-режиме поднимал AvitoBlockedError на ЛЮБОЙ отказ
  сайдкара (503 «browser unavailable», ConnectError, пустой пул) — то есть
  диагноз врал даже там, где передавался. Теперь — AvitoSidecarUnavailableError,
  подтип AvitoRateLimitedError: поведение прогона и чекпоинт не меняются;
- avito_detail_backfill доносит диагнозы своих блоков до финализатора; блоки
  разошлись — 'unknown'. У domclick тип неразделим (один DomClickBlockedError
  и на QRATOR, и на сбое транспорта) — ограничение названо в коде, диагноз
  оттуда не идёт;
- миграция 234: 'unknown' в CHECK (иначе запись падала бы), COMMENT, и перевод
  двух строк, помеченных дефолтом ПОСЛЕ применения 218. Ретро-классификация
  218 по тексту не тронута.

Тесты падают на старом коде: 11 проверок (финализатор, browser-ветка detail,
классификатор, дефолт обеих копий, проводка backfill'а). Живой тест на
CHECK-констрейнт — в skip_allowlist (мок-лэйн БД не имеет).

Refs #2764
bot-backend merged commit 0de22f4bc9 into main 2026-08-06 23:18:00 +00:00
bot-backend deleted branch fix/2764-ban-kind-no-default 2026-08-06 23:18:00 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
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#2765
No description provided.