Знаете, что самое опасное в проде на Python? Когда кто-то говорит:
«Да там всё просто работает».
На старте кажется норм: сервис не падает, пользователи довольны. Но на практике это один из самых тихих способов убить систему. Особенно если речь идёт о except Exception.
Python — мягкий язык. Он позволяет коду жить, даже когда логика трещит по швам. И именно поэтому статус «просто работает» в Python-продакшене — не стабильность, а предвестник скрытых проблем.
Первый раз, когда я это понял
У нас был микросервис, который обрабатывал данные пользователей для аналитики. Всё вроде ок: деплой прошёл, тесты зелёные, метрики в норме. Но через пару недель начали приходить жалобы на отчёты — цифры не сходились.
Я полез в код и увидел это:
try:
value = int(data.get("amount"))
except Exception:
value = 0На первый взгляд вроде безопасно. Но кто-то прислал data = {"amount": "12.5"}. Python бросил ValueError, но блок except Exception поймал всё и вернул 0.
Результат: неделя отчётов с неверными данными. Сервис не упал, тесты не сломались, а данные были испорчены.
Я помню, как в тот день подумал:
«Блять, из-за одной строчки весь пайплайн сгорел, а мы даже не заметили!»
И это был только первый звонок.
Почему except Exception в Python — тихий убийца
Python перехватывает всё подряд. Один блок except Exception — и вы ловите:
ошибки логики,
ошибки данных,
сбои внешних сервисов,
баги других разработчиков.
И всё это выглядит одинаково: сервис работает, тесты проходят, метрики зелёные. Но реальность такая: ты больше не знаешь, что реально происходит.
Когда «работает» превращается в проблему
Пример 1. Дефолтные значения
def is_enabled(config):
try:
return bool(config.get("enabled", True))
except Exception:
return FalseВроде бы безопасно. А вот что реально происходит:
{"enabled": "false"} # True — WTF!
{"enabled": 0} # False
{"enabled": None} # FalseСервис молчит, логи зелёные, тесты проходят. Но фича ведёт себя странно.
И только когда пользователи начинают жаловаться, становится понятно, что код фактически сломал логику, но «не сломался».
Пример 2. Ошибки внешних сервисов
try:
result = external_api_call(data)
except Exception:
result = NoneСервис не падает, пользователи ничего не замечают, лог говорит «всё ок».
Но реальная проблема: external_api_call вернул некорректные данные. Они пошли дальше по цепочке, испортили расчёты и логирование.
Через день аналитики заметили странные отчёты. И да — исключение было поймано, а данные уже «сгорели».
Пример 3. Потеря контекста
Иногда блоки except Exception копятся по всему проекту. И вот результат:
try:
do_step1()
except Exception:
pass
try:
do_step2()
except Exception:
passКаждый шаг молча «теряет» ошибки. В итоге:
новые разработчики боятся трогать код,
code review превращается в гадание «что сломается, если я это поменяю?»,
рефакторинг — минное поле.
И это не гипотетически, а на живом проде, где один неправильный фикс может испортить аналитические отчёты на месяц.
Почему баги живут годами
Исключение уже обработано → стек-трейс потерян.
Лог не выглядит опасно → никто не ищет причину.
Поведение «плавает» → воспроизвести сложно.
Система работает → создаётся иллюзия стабильности.
И это настоящий кошмар для команды: сервис вроде жив, а доверие к нему улетает в трубу.
Тесты не спасают
проверяют только happy path;
мокают внешние зависимости;
не учитывают «странные» данные;
не проверяют цепочки вызовов через несколько сервисов.
Всё, что скрывается под except Exception, тесты не видят. Ты думаешь, что всё ок, а на деле половина данных неверна, а логика сломана.
Как жить с этим в Python
Статья не про запрет except Exception. Она про осознанное использование:
ловить только конкретные исключения, а не всё подряд;
логировать ошибки с полным контекстом;
валидировать входные данные перед обработкой;
позволять сервису падать там, где это безопасно, чтобы баги не копились;
добавлять юнит-тесты с нестандартными кейсами, чтобы ловить «странные» данные.
Вывод
В Python «просто работает» — это не стабильность.
Это тихий враг, который делает код живым, но непредсказуемым.
Он маскирует ошибки, разрушает доверие и усложняет поддержку.
Если вы поймёте, что не можете объяснить, почему код работает, — это отличный повод остановиться, разобраться и перестать надеяться на чудо.