Перейти к содержанию
Innovialabs

Как читать stack trace и находить ошибку

Практика4 мин

Коротко

Stack trace — это цепочка вызовов до места падения: найдите тип и текст ошибки, затем первый фрейм из вашего кода — там почти всегда и нужно чинить.

Что такое stack trace и с чего начинать

Stack trace — это список вызовов функций, которые были активны в момент ошибки. Каждая строка — фрейм: файл, номер строки и имя функции. Читать его нужно в два шага:

  1. Найдите тип и сообщение ошибки — это ответ на вопрос «что случилось».
  2. Найдите первый фрейм из вашего кода — это ответ на вопрос «где чинить».

Главная сложность в том, что языки выводят стек в разном порядке. Разберём три примера.

Python: читаем снизу вверх

Traceback (most recent call last):
  File "/app/main.py", line 12, in <module>
    total = calculate_total(order)
  File "/app/billing.py", line 8, in calculate_total
    return sum(item["price"] * item["qty"] for item in order["items"])
  File "/app/billing.py", line 8, in <genexpr>
    return sum(item["price"] * item["qty"] for item in order["items"])
KeyError: 'qty'
  • Фраза most recent call last означает: самый свежий вызов — внизу.
  • Последняя строка — сама ошибка: KeyError: 'qty', в словаре нет ключа qty.
  • Строка над ней — точное место: billing.py, строка 8.
  • Выше — путь, которым программа туда пришла: main.py вызвал calculate_total.

Вывод: в одном из товаров заказа нет поля qty. Чинить нужно либо данные, либо функцию (например, item.get("qty", 1), если это допустимо по логике).

Если в трейсе есть фраза During handling of the above exception, another exception occurred, значит, ошибок две: первая — исходная причина, вторая возникла при её обработке. Начинайте с первой.

JavaScript (Node.js): читаем сверху вниз

TypeError: Cannot read properties of undefined (reading 'map')
    at renderList (/app/src/list.js:14:22)
    at handleRequest (/app/src/server.js:31:10)
    at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5)
  • Первая строка — тип и сообщение: у undefined пытались вызвать .map.
  • Сразу под ней — место падения: list.js, строка 14, колонка 22.
  • Ниже — кто вызывал. Фреймы из node_modules — это библиотека (здесь Express), их обычно можно пропустить.

Вывод: в renderList пришёл массив, которого нет. Смотрите, что передаёт handleRequest на строке 31.

В браузере стек может указывать на минифицированный бандл вроде main.3f2a.js:1:48213. Чтобы видеть исходные файлы, включите source maps в сборке и в DevTools.

Java: сверху вниз и обязательно «Caused by»

Exception in thread "main" java.lang.IllegalStateException: Failed to load config
	at com.example.App.loadConfig(App.java:42)
	at com.example.App.main(App.java:15)
Caused by: java.lang.NumberFormatException: For input string: "abc"
	at java.base/java.lang.Integer.parseInt(Integer.java)
	at com.example.Config.port(Config.java:27)
	at com.example.App.loadConfig(App.java:40)
	... 1 more

(Пример упрощён.)

  • Верхняя ошибка — «обёртка»: конфиг не загрузился.
  • Настоящая причина — в блоке Caused by, и самый нижний такой блок обычно самый важный.
  • В нём первый фрейм java.base — это стандартная библиотека, а первый ваш фрейм — Config.java:27: туда пришла строка "abc" вместо числа.
  • ... 1 more значит, что оставшиеся фреймы совпадают с уже показанными выше.

Как найти свой код среди чужих фреймов

  • Ищите пути вашего проекта: /app/src, com.yourcompany, имя репозитория.
  • Пропускайте node_modules, site-packages, java.base, org.springframework и похожие — ошибка в библиотеке встречается намного реже, чем неверные данные, переданные в неё.
  • Если ваших фреймов нет совсем, ошибка, скорее всего, в конфигурации или окружении: версии пакетов, переменные окружения, права на файлы.
  • Многие IDE подсвечивают фреймы проекта и делают их кликабельными — пользуйтесь этим.

Как эффективно искать ошибку в интернете

  1. Копируйте тип и сообщение, а не весь трейс: TypeError: Cannot read properties of undefined.
  2. Убирайте всё уникальное: пути, ID, имена ваших переменных, даты.
  3. Добавляйте название библиотеки или фреймворка и его мажорную версию.
  4. Берите точную фразу в кавычки.
  5. Смотрите issues на GitHub у библиотеки — там часто есть и причина, и обходной путь.
  6. Если ответ старый, сверяйте его с вашей версией.

Частые ошибки при чтении трейса

  • Смотреть только на последнюю строку и игнорировать «Caused by».
  • Чинить место падения, а не место, где появились плохие данные.
  • Удалять трейс из логов или логировать только error.message без стека.
  • Глушить исключение пустым catch/except — стек теряется навсегда.

Частые вопросы

Падение происходит там, где плохие данные используются, а не там, где они появились. Поднимайтесь по стеку вверх по вызовам и ищите, откуда пришло неверное значение.

Поможем с этим

Если хотите не разбираться самим, а получить результат — этим мы занимаемся каждый день.

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.