Читать ошибки как взрослый
Вайбкодер видит ошибку и сразу копирует её в Claude или гугл. Часто срабатывает, но не учит. Если ты потратишь 30 секунд чтобы РАЗОБРАТЬ ошибку прежде чем спрашивать ИИ — будешь решать в 5 раз быстрее. Стек-трейс это не магия, это карта. Учимся её читать.
Анатомия ошибки
Любая ошибка в JS состоит из 3 частей: (1) **Тип ошибки** — TypeError, ReferenceError, SyntaxError, и т.д. Каждый тип означает свой класс проблемы. (2) **Сообщение** — конкретно что не так. «Cannot read property X of undefined» это совсем другое чем «X is not a function». (3) **Stack trace** — список вызовов которые привели к ошибке, СНИЗУ ВВЕРХ во времени. Самая верхняя строка = место где упало. Ниже = кто это вызвал. Ещё ниже = кто вызвал того. Дойти до твоего кода в этом списке — главная задача.
Главные типы ошибок и что они значат
**TypeError: Cannot read property X of undefined/null** — обращение к свойству у несуществующего объекта. Самая частая ошибка. Проверь что переменная которую дёргаешь действительно существует на этом этапе. **TypeError: X is not a function** — пытаешься вызвать как функцию что-то что функцией не является. Часто опечатка в имени или забытый импорт. **ReferenceError: X is not defined** — переменной не существует в этой области видимости. Опечатка или забытый импорт. **SyntaxError** — синтаксическая ошибка, код не парсится. Чаще всего это не там где ругается, а на пару строк выше — пропущенная скобка/запятая. **NetworkError / fetch failed** — проблема с сетью или невалидный URL. **ECONNREFUSED** — сервис не запущен на этом адресе.
Стек-трейс — читаем сверху
Открыл стек, видишь 30 строк. Большинство — внутренности библиотек. Твоя цель — найти ПЕРВУЮ строку которая ссылается на ТВОЙ файл. Это место где ошибка стартовала в твоём коде. Часто она единственная. Игнорируй строки вида node_modules/react-dom/... или /node_modules/next/... — они не помогают (это не баг библиотеки, это твой код использовал её неправильно). Twoя строка типа src/app/page.tsx:47:23 → файл, строка 47, символ 23. Идёшь туда. Вот корень проблемы.
Source maps — превращают минифицированный кошмар в нормальный код
В проде ошибки часто выглядят как
Это потому что код минифицирован: имена сжаты в одну букву. Source maps — файлы которые маппят минифицированный код обратно на исходный. В Next.js они генерируются автоматически в dev. В Sentry/LogRocket надо включить и аплоадить source maps при деплое. Без них на проде ты слепой. Стандарт для прода — настроить Sentry + загрузка source maps в CI.
Алгоритм когда видишь ошибку
По шагам: (1) Прочитай ТИП ошибки и сообщение. Понял о чём она? Если нет, отдельно загугли тип ошибки за 30 секунд. (2) Найди ПЕРВУЮ строку стека где упоминается твой файл. (3) Открой это место в редакторе. Какая переменная/функция тут? Вот эта переменная — есть ли она вообще на этом этапе? (4) Console.log переменную ВЫШЕ строки ошибки. Проверь что там. (5) Если разобрался — фикси. Если нет — теперь спрашиваешь ИИ, дав ему: ошибку + типаж + что ты уже проверил. Так получишь толковый ответ за один шаг, а не диалог из 10 итераций.
TypeError: Cannot read properties of undefined (reading 'name')
at UserCard (/Users/me/proj/src/components/UserCard.tsx:12:23)
at renderWithHooks (/proj/node_modules/react-dom/cjs/react-dom.development.js:16312:18)
at mountIndeterminateComponent (...)
at beginWork (...)
at performUnitOfWork (...)
at workLoopSync (...)
at renderRootSync (...)
at performSyncWorkOnRoot (...)
# Разбор:
# 1. Тип: TypeError → нарушение типа
# 2. Сообщение: Cannot read 'name' of undefined → пытаешься достать .name у undefined
# 3. Стек, первая твоя строка: UserCard.tsx, строка 12, символ 23
# Открываем UserCard.tsx:12:
#
# const UserCard = ({ user }) => {
# return <div>{user.name}</div>; // ← вот эта строка
# };
#
# Значит user.name → user это undefined.
# Значит компонент вызвали без пропа user или с user={undefined}
# Идём искать вызов <UserCard /> в коде:
#
# // В parent компоненте:
# {users.map(u => <UserCard />)} // ← вот, забыли передать user
#
# Должно быть:
# {users.map(u => <UserCard user={u} key={u.id} />)}
#
# Готово. Решено за 30 секунд без гугла, без ИИ, без чата.Реальная ошибка — разбираем по шагам