Введение в ошибки в JavaScript
Введение в ошибки в JavaScript
Технический фундамент ошибок в рантайме
Чтобы уверенно работать с ошибками, важно понимать базовую механику исполнения JS:
- JavaScript выполняет код последовательно по стэку вызовов;
- при непойманном исключении текущий поток выполнения прерывается;
- ошибка содержит тип, сообщение и stack trace;
- источник сбоя часто находится на границе данных, а не в месте, где упало.
Фундаментальный навык: сначала классифицировать тип ошибки (синтаксис, рантайм, логика), потом исправлять причину.
Зачем вообще разбираться с ошибками
Когда ты начинаешь писать код, кажется, что ошибка это просто "что-то сломалось". В реальной разработке это часть повседневной работы: данные приходят не в том формате, пользователь вводит мусор, API отвечает нестабильно, а коллега случайно меняет контракт функции. Если ты понимаешь природу ошибок, ты не паникуешь при красном стеке, а быстро находишь причину.
Ключевой момент: ошибка в JavaScript это сигнал о том, что код не может корректно продолжить выполнение в текущем состоянии. Иногда выполнение останавливается сразу, иногда проблема проявляется позже как "странное поведение".
Проверь себя: почему в проде опаснее тихая логическая ошибка, чем явный SyntaxError?
Какие ошибки бывают чаще всего
На старте полезно разделить ошибки на 3 группы:
- синтаксические (
SyntaxError) - код нельзя даже разобрать; - ошибки времени выполнения (
TypeError,ReferenceErrorи другие) - код запустился, но упал в процессе; - логические ошибки - код работает без падения, но результат неверный.
Смотри, что важно: try...catch помогает только с ошибками, которые происходят во время выполнения (runtime).
Синтаксическая ошибка в коде (когда файл не парсится) остановит запуск скрипта, и try...catch в этом же файле не спасет.
При этом тип SyntaxError может встретиться и как runtime-ошибка, например при парсинге JSON:
try {
JSON.parse('{bad json}');
} catch (error) {
console.log(error.name); // SyntaxError
}
Смотри, что важно: третья категория самая коварная. Приложение не падает, но бизнес-логика ломается, и баг замечают пользователи.
const price = 100;
const discount = 20;
// Логическая ошибка: ожидали 80, получили 2000
const total = price * discount;
console.log(total);
Код синтаксически валиден, рантайм не ругается, но формула неправильная. Это типичный пример, почему тесты и проверки нужны даже там, где "ничего не падает".
Проверь себя: чем логическая ошибка отличается от TypeError с точки зрения видимости проблемы?
Базовые встроенные типы ошибок
JavaScript уже содержит стандартные классы ошибок. Несколько базовых, которые ты будешь видеть постоянно:
ReferenceError- обращение к переменной, которой нет в области видимости;TypeError- попытка сделать операцию с неподходящим типом;SyntaxError- неправильный синтаксис;RangeError- значение вышло за допустимый диапазон.
function printUser(user) {
console.log(user.name.toUpperCase());
}
printUser(null); // TypeError: Cannot read properties of null
Здесь часто путаются: ошибка не в toUpperCase, а в том, что user равен null, и у него нет свойства name. То есть корневая причина обычно находится чуть раньше места падения.
Проверь себя: какая минимальная проверка перед user.name спасет код от падения?
Почему ошибки появляются в реальных сценариях
Ошибки чаще всего приходят из границ системы:
- пользовательский ввод: пустые строки, пробелы, неожиданные символы;
- внешние данные: API может вернуть
nullили неполный объект; - несогласованность кода: функция ожидает одно, а получает другое;
- изменения в проекте: рефакторинг сломал старые места вызова.
Мини-сценарий: форма регистрации. Ты ждешь email-строку, а приходит undefined. Если сразу вызвать trim(), получишь TypeError.
function normalizeEmail(email) {
if (typeof email !== 'string') return null;
return email.trim().toLowerCase();
}
console.log(normalizeEmail(' USER@MAIL.COM ')); // user@mail.com
console.log(normalizeEmail(undefined)); // null
Дополнительный пример: защита от ReferenceError через явную область видимости.
function printTotal() {
const total = 100;
console.log(total);
}
printTotal();
// console.log(total); // ReferenceError: total is not defined
Анти-провал: сначала валидируй вход, потом вызывай методы. Не наоборот.
Стек вызовов и чтение сообщения об ошибке
Когда ошибка выбрасывается, JavaScript показывает:
- тип ошибки (
TypeError,ReferenceError); - сообщение (
Cannot read properties of null); - stack trace - цепочку вызовов до места падения.
Смотри, что важно: не начинай дебаг с верхней строчки файла "наугад". Сначала прочитай тип и текст ошибки, потом найди строку, где она возникла, и только после этого двигайся вверх по вызовам.
Мини-сценарий: обработка данных API.
renderProfileвызываетformatName;formatNameожидаетuser.firstName;- API вернул объект без
firstName; - падаешь в
formatName, но причина в контракте данных.
Проверь себя: почему исправление только в renderProfile может не решить проблему системно?
Частые ошибки новичков
- Игнорировать текст ошибки и смотреть только на красный экран.
- Сразу переписывать много кода вместо локальной проверки входов.
- Логировать слишком мало (не видно данных) или слишком много (шум).
- Считать, что "если не упало, значит работает правильно".
Еще одна частая ловушка: пытаться лечить симптом, а не причину. Например, ставить "магические" проверки в одном месте, когда нужно исправить формат данных на границе модуля.
Небольшой рабочий флоу отладки на старте
- Зафиксируй точный сценарий: какие данные и шаги приводят к багу.
- Прочитай тип ошибки и сообщение полностью.
- Найди место падения по stack trace.
- Проверь входные данные в этой точке.
- Сформулируй гипотезу и проверь минимальным изменением.
Это простой процесс, но он сильно ускоряет работу и снижает "хаотичную" отладку.
Проверь себя: зачем сначала воспроизводить баг стабильно, а не сразу править код?
Краткий итог
- Ошибки в JavaScript это нормальная часть разработки, а не "провал".
- Есть синтаксические, runtime и логические ошибки, и каждая требует своего подхода.
- Самые частые падения у новичков связаны с неверными типами и отсутствующими значениями.
- Корневая причина часто находится на границе данных, а не в строке, где упало.
- Четкий флоу: воспроизвести -> прочитать сообщение -> проверить вход -> исправить причину.