Phase A не пагинирует и молча теряет хвост объектов при limit=999999, run всё равно 'done' #1605

Closed
opened 2026-06-16 17:17:21 +00:00 by bot-backend · 0 comments
Collaborator

Severity: medium · Категория: pagination / silent-truncation / false-report · Файл: backend/app/services/scrapers/domrf_kn.py:1435-1453

domrf_kn.py:1450-1452 — fetch_objects_for_status делает единственный запрос (offset=0, limit=999999) и возвращает _extract_list(payload). total из _extract_total(payload) только логируется (строка 1452), но НЕ сверяется с len(rows) и не используется для дозагрузки страниц. Docstring строки 1438 декларирует недоказанное допущение 'server returns up to limit=999999'.

ИМПАКТ: если сервер/WAF/прокси DOM.РФ ограничивает фактический размер страницы (типичная реакция на гигантский limit — обрезка до своего max), то len(rows) < total, и объекты сверх первой страницы НИКОГДА не попадают в all_objects (Phase A, domrf_kn.py:1740-1742) → не скрейпятся (нет квартир/документов/sale_graph по ним). При этом run доходит до Phase D и ставит status='done' (1942), а objects_count/total_obj_count фиксируют только полученную страницу (1786). Тихий недобор без единого WARNING — 'ложь в отчёте' о полноте по региону.

ФИКС: либо реальная пагинация (цикл offset += page_size до len(accumulated) >= total), либо как минимум жёсткая проверка len(rows) == total с logger.warning/raise при расхождении, чтобы недобор не маскировался статусом 'done'.

Почему баг: Если сервер/WAF/прокси DOM.РФ ограничивает фактический размер страницы (типичное поведение при гигантском limit — сервер режет до своего max page size), то len(rows) < total, и все объекты сверх первой страницы НИКОГДА не попадают в all_objects → не скрейпятся (квартиры/документы/sale_graph по ним отсутствуют), а run при этом доходит до Phase D и проставляет status='done'. Это и потеря данных, и 'ложь в отчёте': итоговый objects=total в результате и в kn_scrape_runs отражает только полученную страницу, а не реальную полноту по региону. Тихий молчаливый недобор без единого WARNING.

Как чинить: Сделать цикл пагинации по offset с фиксированным page-limit до достижения total (или до пустой страницы); при mismatch len(rows) != total — logger.warning и/или пометить run как partial. Минимум — явно сравнивать total с накопленным count и логировать WARNING при расхождении, чтобы недобор не маскировался под 'done'.


deep-audit backend v2 (после PR #1543) · verify+harden, confidence 0.72 · unit B31

**Severity:** medium · **Категория:** pagination / silent-truncation / false-report · **Файл:** `backend/app/services/scrapers/domrf_kn.py:1435-1453` domrf_kn.py:1450-1452 — fetch_objects_for_status делает единственный запрос (offset=0, limit=999999) и возвращает _extract_list(payload). total из _extract_total(payload) только логируется (строка 1452), но НЕ сверяется с len(rows) и не используется для дозагрузки страниц. Docstring строки 1438 декларирует недоказанное допущение 'server returns up to limit=999999'. ИМПАКТ: если сервер/WAF/прокси DOM.РФ ограничивает фактический размер страницы (типичная реакция на гигантский limit — обрезка до своего max), то len(rows) < total, и объекты сверх первой страницы НИКОГДА не попадают в all_objects (Phase A, domrf_kn.py:1740-1742) → не скрейпятся (нет квартир/документов/sale_graph по ним). При этом run доходит до Phase D и ставит status='done' (1942), а objects_count/total_obj_count фиксируют только полученную страницу (1786). Тихий недобор без единого WARNING — 'ложь в отчёте' о полноте по региону. ФИКС: либо реальная пагинация (цикл offset += page_size до len(accumulated) >= total), либо как минимум жёсткая проверка len(rows) == total с logger.warning/raise при расхождении, чтобы недобор не маскировался статусом 'done'. **Почему баг:** Если сервер/WAF/прокси DOM.РФ ограничивает фактический размер страницы (типичное поведение при гигантском limit — сервер режет до своего max page size), то len(rows) < total, и все объекты сверх первой страницы НИКОГДА не попадают в all_objects → не скрейпятся (квартиры/документы/sale_graph по ним отсутствуют), а run при этом доходит до Phase D и проставляет status='done'. Это и потеря данных, и 'ложь в отчёте': итоговый objects=total в результате и в kn_scrape_runs отражает только полученную страницу, а не реальную полноту по региону. Тихий молчаливый недобор без единого WARNING. **Как чинить:** Сделать цикл пагинации по offset с фиксированным page-limit до достижения total (или до пустой страницы); при mismatch len(rows) != total — logger.warning и/или пометить run как partial. Минимум — явно сравнивать total с накопленным count и логировать WARNING при расхождении, чтобы недобор не маскировался под 'done'. --- <sub>deep-audit backend v2 (после PR #1543) · verify+harden, confidence 0.72 · unit B31</sub>
bot-backend added the
week ревью 1
label 2026-06-16 17:17:21 +00:00
Sign in to join this conversation.
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#1605
No description provided.