Привет, Хабр! Меня зовут Андрей, как и многие, я уставал от красных сообщений об ошибках в консоли, где не видно значений переменных. Приходилось ставить print(), гуглить – терял кучу времени. Поэтому я написал crashprobe – библиотеку, которая делает отладку простой и наглядной.
Проблема
Я думаю, всем, у кого программа падала из-за ошибки, надоело вот это:
Такое сообщение неинформативно, и вот почему:
-
В нём нет списка локальных переменных и их значений во время падения
-
В нём нет контекста кода
-
В нём нет ссылок на документацию (нужно самостоятельно гуглить)
В общем, такого сообщения порой не достаточно для решения проблемы. Поэтому я и решил сделать инструмент, который даёт всю нужную информацию сразу.
Решение: crashprobe
Я решил написать библиотеку, которая автоматически собирает всю нужную информацию об ошибке и показывает её в удобном виде.
Вот как та же самая ошибка выглядит с crashprobe:
Что умеет crashprobe (версия 0.4.0)
-
Перехватывает любые необработанные исключения в синхронном коде и в любых потоках (через
threading.excepthook). -
Генерирует HTML‑отчёт (тёмная тема, эмодзи, кнопка копирования) или TXT‑файл (для консоли, удобно на серверах).
-
Показывает локальные переменные (с типами) для каждого фрейма стека.
-
Показывает контекст кода – несколько строк вокруг проблемной, с подсветкой строки ошибки.
-
Добавляет системную информацию (версия Python, ОС, hostname, имя и ID потока).
-
Умеет скрывать пароли/токены через параметр
hide_secrets=["password", ...]. -
Не имеет внешних зависимостей – только стандартная библиотека Python.
Как начать пользоваться
Установка – одна команда:
pip install crashprobe
И две строчки в вашем коде:
import crashprobecrashprobe.start()
После этого любая необработанная ошибка автоматически сгенерирует отчёт и откроет его в браузере (или напечатает в консоль, если выбран TXT-формат).
Пример с ошибкой:
def divide(a, b): return a / bprint(divide(1, "Hello")) # TypeError: unsupported operand type(s) for /: 'int' and 'str'
Вместо скучного сообщения в консоли вы увидите красивую HTML-страницу с подробностями.
Настройка: как изменить поведение crashprobe
У функции crashprobe.start() есть три необязательных параметра. Они позволяют адаптировать библиотеку под разные сценарии.
|
Параметр |
Тип |
По умолчанию |
Краткое описание |
|---|---|---|---|
|
|
|
|
Автоматически открывать отчёт (в браузере для HTML, печатать в консоль для TXT) |
|
|
|
|
Формат отчёта: |
|
|
|
|
Список ключевых слов. Если имя переменной содержит любое из них, её значение заменится на |
Подробнее о каждом параметре
-
auto_open-
Если
True, HTML-отчёт открывается в браузере, а TXT-отчёт печатается прямо в консоль. -
Если
False, файл только сохраняется в папкуимя_файла_crash_dir. Удобно для серверов без графического интерфейса.
-
-
file_format-
"HTML"– генерируется красивая веб-страница с тёмной темой, эмодзи, кнопкой копирования. -
"TXT"– создаётся текстовый файл, который легко просматривать в любом редакторе или в терминале.
-
-
hide_secrets-
Передаётся список строк, например
["password", "token", "api_key"]. -
При сборе локальных переменных библиотека проверяет имя каждой переменной: если оно содержит одну из этих подстрок (регистр не важен), значение заменяется на
<hidden>(тип переменной сохраняется). -
Это помогает случайно не «засветить» пароли, ключи API и другие чувствительные данные в отчётах.
-
Примеры использования
python
import crashprobe# 1. Поведение по умолчанию (HTML, автопоказ)crashprobe.start()# 2. Только сохранить TXT, не показывать в консолиcrashprobe.start(auto_open=False, file_format="TXT")# 3. Скрыть переменные, в имени которых есть "password" или "token"crashprobe.start(hide_secrets=["password", "token"])
Полное описание всех аргументов и их допустимых значений можно найти в документации на PyPI.
Почему это удобно?
-
Экономит время – не нужно вручную копировать трейсбек, гуглить, добавлять
print(). -
Помогает новичкам – сразу видно, какие значения были в переменных.
-
Полезно для профи – полная информация о потоке, системные данные.
-
Можно поделиться – сохранить HTML-файл и отправить коллеге.
Как устроена библиотека (технические детали)
Crashprobe не использует никаких сторонних библиотек – только стандартные модули Python. В основе лежат несколько простых, но мощных идей.
1. Перехват исключений
-
В синхронном коде – библиотека подменяет
sys.excepthook. Это стандартный механизм Python, который вызывается при любом необработанном исключении. Crashprobe устанавливает туда свою функцию, которая и начинает обработку. -
В потоках – обычный
sys.excepthookне срабатывает. Поэтому дополнительно переопределяетсяthreading.excepthook. Он передаёт в обработчик три аргумента (exc_type,exc_value,exc_traceback), упакованные в один объект, поэтому я написал небольшую функцию-обёртку, которая распаковывает их и вызывает основную логику. Так одна и та же функция_error_catchingработает и для главного потока, и для дополнительных.
2. Сбор локальных переменных
Когда происходит ошибка, я получаю последний фрейм стека (tb.tb_frame), а затем перебираю все его локальные переменные через frame.f_locals. Чтобы отсеять мусор, я исключаю:
-
встроенные имена, начинающиеся и заканчивающиеся на (например,
__name__,и т.д.); -
callable-объекты (функции, классы);
-
модули (
<class 'module'>).
Для каждого ключа я сохраняю имя, значение (через repr()) и тип (type(val).__name__).
3. Контекст кода
Чтобы показать строки вокруг ошибки, используется linecache.getline(filename, line_number). Я беру 2 строки до и 2 после ошибочной. Для HTML-отчёта строка с ошибкой оборачивается в <div class="errorStr"> и получает красный фон.
4. Генерация HTML и TXT
HTML – это шаблон со встроенным CSS (тёмная тема). Все данные вставляются через f-строки. Кроме того, добавлен небольшой JavaScript, который копирует содержимое страницы в буфер обмена (кнопка «Click to copy»).
TXT – такой же набор данных, но без HTML-тегов, с разделителями из подчёркиваний. Если auto_open=True, TXT-отчёт не открывается в редакторе, а печатается прямо в консоль – это удобно для серверов.
5. Скрытие секретов
Параметр hide_secrets принимает список ключевых слов (например, ["password", "token"]). При обходе локальных переменных проверяется, содержит ли имя переменной любое из этих слов. Если да, то значение заменяется на <hidden> (тип при этом сохраняется). Это простое, но эффективное решение, чтобы случайно не «засветить» пароли в отчётах.
6. Нет зависимостей
Все перечисленные механизмы – sys, threading, linecache, html, pathlib, webbrowser, platform – входят в стандартную библиотеку Python. Это значит, что для установки crashprobe не нужно тянуть десятки сторонних пакетов. Библиотека работает сразу после pip install.
Сравнение с аналогами
Чтобы понять чем crashprobe отличается от своих аналогов, посмотрим на таблицу:
|
Инструмент |
Перехват ошибок в потоках |
Зависимости |
Создание HTML отчёта |
Скрытие значений конфиденциальных переменных |
|
crashprobe |
✓ |
нет |
✓ |
✓ |
|
rich (traceback) |
✕ |
есть |
✕ |
✕ |
|
Django Debug Toolbar |
✕ |
есть |
✓ |
✕ |
|
better-exceptions |
✕ |
есть |
✕ |
✕ |
Как видно, crashprobe – единственный инструмент, который одновременно:
-
Ловит ошибки в потоках
-
Не имеет внешних зависимостей
-
Создаёт автономный HTML отчёт
-
Скрывает значения конфиденциальных переменных в отчётах
Статистика и достижения
Crashprobe уже показывает хорошие результаты, хотя я почти не занимался продвижением.
Пик популярности
Сразу после выхода версии 0.4.0 библиотека входила в топ‑25% всех Python‑пакетов на PyPI (обгоняла 75% библиотек). В тот момент её место было примерно 180‑тысячное среди более чем 900 000 пакетов.
Текущая ситуация
Со временем активность немного снизилась (это нормально: пик новизны прошёл, пользователи перешли к повседневному использованию). Сейчас crashprobe находится в верхней части топ‑30% (примерно 282‑тысячное место), что всё равно означает, что она обгоняет около 70% всех библиотек на PyPI.
Для сравнения: большинство пакетов на PyPI получают 0–5 установок в месяц. У crashprobe в среднем около 20 установок в день, и это не считая возможных всплесков после публикации статей.
Что это значит
-
Библиотека нужна разработчикам – её регулярно скачивают.
-
Даже без активной рекламы проект остаётся в верхней трети рейтинга.
-
Как только я начну рассказывать о crashprobe на Хабр и других площадках, позиции могут снова вырасти.
Я не хочу приукрашивать: популярность немного снизилась после пика, но это естественный процесс. Главное – библиотека продолжает жить и помогать людям.
Честные ограничения
-
Пока нет поддержки асинхронного кода
-
Пока нет интеграций с популярными фреймворками (Django, Flask, FastAPI)
Планы на будущее
-
Поддержка асинхронного кода (asyncio)
-
Интеграции с популярными фреймворками (Django, Flask, FastAPI)
-
Улучшение HTML и TXT отчётов
Ссылки
Заключение
Спасибо, что дочитали до конца! Я создал crashprobe, потому что сам уставал от неудобной отладки, надеюсь моя библиотека сэкономит вам много времени.
Пожалуйста, попробуйте crashprobe в своём проекте, поделитесь мнением и расскажите знакомым о библиотеке. Установка – одна команда, использование – две строки кода. Вы ничего не теряете, а выиграть можете много времени.
Давайте вместе сделаем отладку Python проще, удобнее и красивее!
ссылка на оригинал статьи https://habr.com/ru/articles/1044368/