Недоступный Telegram отдаёт 502, а не 500 #3456

Merged
lekss361 merged 1 commit from fix/tg-network-error-502 into main 2026-09-12 00:08:47 +00:00
Owner

Прод 11.09.2026, 01:35 и 01:38 MSK — два 500 на POST /api/v1/trade-in/ops/glitchtip-webhook. Причина не в вебхуке.

TelegramClient._request после исчерпания сетевых ретраев делал голый raise, и наружу летел httpx.ConnectTimeout. Все три HTTP-ручки ловят TelegramApiError — сырой httpx пролетал мимо, FastAPI отдавал 500 вместо задуманного 502. Для вызывающего отказ площадки и её недоступность неразличимы: переслать не смогли и там, и там.

Что сделано

Клиент больше не выпускает наружу чужой тип. Иерархия:

  • TelegramError — общий предок;
  • TelegramApiError — площадка ответила ok: false (как было);
  • TelegramNetworkError — ответа не было, ретраи исчерпаны (новый).

Раздельно, а не наследником: у сетевого отказа нет ни error_code, ни description, брать их неоткуда. И bridge по error_code == 403 разбирает «бот заблокирован» — недоступность в этот разбор попадать не должна. Исходное исключение сохраняется в __cause__, так что в GlitchTip по-прежнему видно, таймаут это соединения или сброс TLS (#3156).

Три ручки ловят предок: вебхук GlitchTip и обе ручки поддержки, авторизованная и анонимная.

Что НЕ менялось

Воркеры. Poll loop в bridge и так ловит Exception, бюджеты ретраев и потолки отката прежние — тесты на них остались, изменился только ожидаемый тип исключения.

Тесты

Пять новых: два на клиенте (свой тип наружу, причина не потеряна, это не TelegramApiError), три на ручках (502 на недоступности, ничего не персистится, анонимной куки не выдаём). Четыре теста бюджета ретраев ждали httpx.ConnectTimeout — ждут новый тип.

Полный прогон: 5907 passed, 37 skipped.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VQ8jqr4SFirX5tFLwdSrXh

Прод 11.09.2026, 01:35 и 01:38 MSK — два 500 на `POST /api/v1/trade-in/ops/glitchtip-webhook`. Причина не в вебхуке. `TelegramClient._request` после исчерпания сетевых ретраев делал голый `raise`, и наружу летел `httpx.ConnectTimeout`. Все три HTTP-ручки ловят `TelegramApiError` — сырой httpx пролетал мимо, FastAPI отдавал 500 вместо задуманного 502. Для вызывающего отказ площадки и её недоступность неразличимы: переслать не смогли и там, и там. ## Что сделано Клиент больше не выпускает наружу чужой тип. Иерархия: - `TelegramError` — общий предок; - `TelegramApiError` — площадка ответила `ok: false` (как было); - `TelegramNetworkError` — ответа не было, ретраи исчерпаны (новый). Раздельно, а не наследником: у сетевого отказа нет ни `error_code`, ни `description`, брать их неоткуда. И `bridge` по `error_code == 403` разбирает «бот заблокирован» — недоступность в этот разбор попадать не должна. Исходное исключение сохраняется в `__cause__`, так что в GlitchTip по-прежнему видно, таймаут это соединения или сброс TLS (#3156). Три ручки ловят предок: вебхук GlitchTip и обе ручки поддержки, авторизованная и анонимная. ## Что НЕ менялось Воркеры. Poll loop в `bridge` и так ловит `Exception`, бюджеты ретраев и потолки отката прежние — тесты на них остались, изменился только ожидаемый тип исключения. ## Тесты Пять новых: два на клиенте (свой тип наружу, причина не потеряна, это не `TelegramApiError`), три на ручках (502 на недоступности, ничего не персистится, анонимной куки не выдаём). Четыре теста бюджета ретраев ждали `httpx.ConnectTimeout` — ждут новый тип. Полный прогон: 5907 passed, 37 skipped. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01VQ8jqr4SFirX5tFLwdSrXh
lekss361 added 1 commit 2026-09-12 00:03:05 +00:00
fix(tg): недоступный Telegram отдаёт 502, а не 500
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 10s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
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 Trade-In / backend-tests (pull_request) Successful in 5m8s
46326ba96e
Прод 11.09.2026, 01:35 и 01:38 MSK — два 500 на glitchtip-webhook. Причина не
в вебхуке: `TelegramClient._request` после исчерпания сетевых ретраев делал
голый `raise`, наружу летел `httpx.ConnectTimeout`. Все три HTTP-ручки ловят
`TelegramApiError` — сырой httpx пролетал мимо, и FastAPI отдавал 500 вместо
задуманного 502. Отказ площадки и её недоступность для вызывающего
неразличимы: переслать не смогли и там, и там.

Клиент больше не выпускает наружу чужой тип. Появился общий предок
`TelegramError`, под ним прежний `TelegramApiError` (ответили `ok: false`) и
новый `TelegramNetworkError` (не ответили вовсе). Раздельно, а не наследником,
потому что у сетевого отказа нет ни `error_code`, ни `description` — брать их
неоткуда, а `bridge` по `error_code == 403` разбирает «бот заблокирован» и
недоступность в этот разбор попадать не должна. Причина сохраняется в
`__cause__`: в GlitchTip по-прежнему видно, таймаут это соединения или сброс
TLS (#3156).

Три ручки — вебхук GlitchTip и обе ручки поддержки, авторизованная и
анонимная — ловят предок. Поведение воркеров не менялось: poll loop в
`bridge` и так ловит `Exception`, бюджеты ретраев те же.

Тесты: два в клиенте (свой тип наружу, причина не потеряна, это НЕ
`TelegramApiError`), три на ручках (502 на недоступности, ничего не
персистится, анонимной куки не выдаём). Четыре теста бюджета ретраев ждали
`httpx.ConnectTimeout` — ждут новый тип, проверяемые паузы прежние.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ8jqr4SFirX5tFLwdSrXh
lekss361 merged commit ec245cf2b3 into main 2026-09-12 00:08:47 +00:00
lekss361 deleted branch fix/tg-network-error-502 2026-09-12 00:08:47 +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#3456
No description provided.