Отладка занимает заметную часть рабочего времени, но её редко разбирают как навык: считается, что умение искать ошибки приходит само. На практике разница между «полдня ловил ошибку» и «нашёл за двадцать минут» почти всегда в методе, а не в стаже. Ниже — порядок, которым мы пользуемся на поддержке чужих проектов, где кода много, документации нет, а автор недоступен.
Порядок, который экономит время
- Воспроизвести. Пока ошибка не повторяется по шагам, её нельзя проверить исправленной. Любое «вроде починили» без воспроизведения — догадка.
- Сузить область. Отключать по половине: данные, участок кода, окружение. Каждый шаг вдвое уменьшает поле поиска.
- Сформулировать гипотезу. «Похоже, приходит пустой массив» — проверяемо. «Что-то с базой» — нет.
- Проверить одним изменением. Меняя три вещи разом, вы не узнаете, что помогло.
- Понять причину. Ошибка, исчезнувшая сама, обычно возвращается в худший момент.
Порядок важен именно в этой последовательности. Самая частая потеря времени — попытка чинить до того, как ошибка воспроизведена, и правка нескольких мест сразу.
Как воспроизвести ошибку
Сообщение «форма не работает» непригодно для работы. Мы уточняем пять вещей: что делал человек, что ожидал увидеть, что увидел, где именно (адрес страницы) и когда. К этому добавляем окружение: браузер, устройство, роль пользователя, был ли он авторизован.
Дальше повторяем шаги сами. Если не воспроизводится, перебираем различия: другой браузер, другая роль, режим без расширений, другой набор данных, другой канал входа. Отдельно проверяем, не связано ли поведение с кэшем — своим, серверным или у поставщика.
Когда шаги найдены, записываем их сразу. Через час детали забываются, а именно они потом становятся сценарием проверки после исправления.
Сужение области: бинарный поиск
Приём простой и работает почти всегда: разделить систему пополам и понять, в какой половине проблема. Поиск ведём по трём осям.
По коду. Проверяем, доходит ли выполнение до нужного места и с какими данными. Убеждаемся, что цикл вообще запускается, а условие срабатывает. Одна проверка в середине подозрительного участка отсекает половину.
По данным. Если сбой происходит на выгрузке из тысячи строк, делим набор пополам и повторяем. Обычно ошибку вызывают несколько записей с пустым полем, нестандартным символом или датой вне диапазона.
По истории изменений. Если раньше работало, ищем коммит, после которого перестало. Половинное деление по истории даёт ответ за несколько шагов даже на большом репозитории; в системах контроля версий для этого есть готовая команда. Найденный коммит редко содержит ошибку сам по себе, но показывает область.
Чем смотреть
| Инструмент | Что показывает | Когда полезен |
|---|---|---|
| Консоль браузера | Ошибки скриптов, предупреждения | Любая проблема на фронтенде |
| Вкладка «Сеть» | Запросы, коды ответов, тело ответа | Форма не отправляется, данные не приходят |
| Логи сервера | Ошибки бэкенда, трассировку | Пятисотые ошибки, сбои обмена |
| Отладчик с точками останова | Значения переменных по шагам | Сложная логика, неочевидные условия |
| Логи в коде | Ход выполнения на боевом сервере | Ошибка не воспроизводится локально |
| Лог запросов к базе | Сами запросы и время их работы | Страница открывается медленно, данные не те |
| Система сбора ошибок | Ошибки у реальных пользователей с контекстом | Жалобы есть, а воспроизвести не удаётся |
Порядок обращения обычно такой: консоль и вкладка «Сеть» отвечают на вопрос, на чьей стороне проблема, дальше подключаются логи сервера, и только затем отладчик — он точнее, но требует времени на подготовку.
Фронтенд и бэкенд: где искать
Прежде чем углубляться, определяем сторону. Открываем вкладку «Сеть» и смотрим на запрос: если он вообще не ушёл — ошибка на фронтенде, скорее всего в скрипте, который прервался раньше отправки. Если ушёл и вернулся с ошибочным кодом — смотрим логи сервера. Если вернулся успешно, но с не теми данными — проблема в бэкенде, но не в падении, а в логике или в самих данных. Если ответ верный, а на странице неправильно — вопрос к отрисовке. Эта проверка занимает минуту и избавляет от самой дорогой ошибки отладки — поисков в той половине системы, где проблемы нет.
Как читать стек-трейс
Трассировку часто пролистывают, хотя в ней обычно есть прямой ответ. Читать её стоит так:
- Сначала тип ошибки и сообщение: обращение к несуществующему полю, деление на ноль, отсутствующий файл, отказ соединения. Тип сужает круг причин сразу.
- Затем — верхняя строка, относящаяся к вашему коду. Строки из библиотек чаще всего показывают место падения, а не источник проблемы.
- Потом путь вызовов сверху вниз: откуда пришли данные, через какие функции они прошли.
- Отдельно смотрим вложенные исключения: исходная причина часто скрыта во второй части сообщения, после отметки о предыдущей ошибке.
Если сообщение неинформативно, добавляем в него контекст: идентификатор записи, входные параметры, имя пользователя. Такая запись в логе экономит следующий разбор.
Ошибка «только на проде»
Самый частый класс задач на поддержке. Проверять стоит по короткому списку:
- Другая версия языка, расширений или библиотек.
- Другие настройки окружения: переменные, лимиты памяти и времени выполнения, размер загружаемого файла.
- Реальные данные с неожиданными значениями: пустые поля, дубли, длинные строки, старые записи.
- Кэш — страниц, шаблонов, скомпилированного кода, ответов внешних сервисов.
- Права доступа к файлам и каталогам, особенно после выкладки.
- Часовой пояс и кодировка сервера.
- Внешние сервисы: платёжный шлюз или почтовый сервис отвечают в боевом режиме иначе, чем в тестовом.
В девяти случаях из десяти причина в этом списке. Если её там нет, включаем подробное логирование на нужном участке, воспроизводим ошибку на бою и разбираем записи. Логи в таком случае делаем адресными: писать всё подряд на нагруженном сайте вредно и для диска, и для скорости.
Плавающие ошибки и данные
Если проблема появляется через раз, почти всегда дело во времени или в порядке событий: гонка запросов, кэш, повторная отправка формы, параллельная обработка одной записи двумя процессами, задача по расписанию, наложившаяся на действия пользователя. Помогает подробное логирование с отметками времени — по нему видна последовательность, которую невозможно поймать вручную.
Отдельная категория — ошибки, которые вызывает не код, а данные. Код написан для нормального случая, а в базе оказывается запись без обязательного поля, товар с нулевой ценой, заказ, ссылающийся на удалённого клиента. Признак такой ошибки характерный: сбой воспроизводится только на конкретных записях. Поэтому первым делом мы смотрим не на код, а на те самые данные, с которыми он падает.
Что делать после исправления
- Пройти записанный сценарий воспроизведения и убедиться, что ошибки больше нет.
- Проверить соседнее поведение: правка условия часто чинит один случай и ломает другой.
- Добавить автоматическую проверку на этот случай, чтобы ошибка не вернулась незамеченной.
- Записать в задаче причину, а не только факт исправления. Через полгода это единственный источник знания о том, почему код выглядит так.
- Проверить, нет ли той же ошибки в других местах: одинаковый шаблон кода обычно повторяется.
Пара привычек, которые заметно сокращают время: не чинить наугад — случайная правка часто прячет симптом, оставляя причину; и если через час нет продвижения, сделать паузу или пересказать проблему коллеге. Формулировка вслух решает задачу удивительно часто.
Возьмём поиск ошибок на себя
Мы разбираем ошибки на чужих проектах регулярно: подключаемся к сайту, находим причину и устраняем её, а не прячем симптом. Если ошибки на сайте повторяются или их некому разбирать, посмотрите техническую поддержку сайта — возьмём мониторинг, разбор обращений и исправления на себя.











