Единственный код 500 означал и «площадка забанила», и «сайдкар упал»:
разбор каждого инцидента начинался с ложного следа — в лог провайдера и в
houses.imv_error_reason уезжала httpx-преамбула «Server error '500 Internal
Server Error' for url 'http://tradein-browser:3000/fetch'», то есть текст
ошибки называл гонца, а не виновника.
- browser/server.py: BanPageDetectedError → 403 (доступ ограничен площадкой);
451 — про юридическую блокировку, это не она. Своих 403 сайдкар не отдаёт
(400/422/503), код однозначен. classify_browser_probe не задета: у неё любой
status >= 400 → "sidecar". Тело не меняется — ban_page/status на месте.
- scraper_kit/browser_fetcher.py: текст SidecarBanPageError теперь свой —
«площадка отдала бан-страницу (upstream 403, ответ сайдкара 403): …».
Распознавание остаётся по ТЕЛУ и code-agnostic: tradein-browser — отдельный
образ со своим деплоем, версии штатно расходятся на часы, и гейт по коду в
этот час уводил бы отказ площадки в инфра-ветку.
- Тесты: 403 → SidecarBanPageError; старый 500 + ban_page → он же; чистый 500
без ban_page → прежний инфра-диагноз; текст ошибки без «500»/«Server error».
Refs #3288 п.4