Обработка ошибок в JavaScript: try...catch, throw и собственные ошибки
Поисковый запрос, под который написана эта статья: обработка ошибок в JavaScript try catch. Если вы уже знаете переменные, функции и условия, самое время разобраться, как правильно реагировать на ошибки, а не просто надеяться, что код всегда выполнится идеально.
Зачем нужна обработка ошибок в JavaScript
Ошибка может возникнуть где угодно: пользователь ввёл неверные данные, сервер вернул неожиданный ответ, JSON оказался битым, нужного элемента нет на странице. Без обработки ошибка может остановить выполнение скрипта и испортить пользовательский опыт.
Главная идея проста: потенциально опасный код помещается в блок try, а реакция на сбой описывается в catch.
try {
const user = JSON.parse('{"name":"Анна"}');
console.log(user.name);
} catch (error) {
console.error('Не удалось разобрать JSON:', error.message);
}
Если внутри try всё хорошо, блок catch не выполняется. Если возникла ошибка, JavaScript передаёт её в catch.
Базовый синтаксис try...catch
Конструкция выглядит так:
try {
// Код, где может произойти ошибка
} catch (error) {
// Что делать, если ошибка произошла
}
Объект error обычно содержит полезные свойства:
- name — тип ошибки, например SyntaxError или TypeError;
- message — текстовое описание;
- stack — стек вызовов, полезен при отладке.
try {
const data = JSON.parse('не json');
} catch (error) {
console.log(error.name); // SyntaxError
console.log(error.message); // описание ошибки
}
Практический пример: безопасный парсинг JSON
Одна из самых частых задач — получить строку JSON и превратить её в объект. Но строка может быть неправильной.
function parseJsonSafe(jsonString) {
try {
return {
ok: true,
data: JSON.parse(jsonString),
error: null
};
} catch (error) {
return {
ok: false,
data: null,
error: 'Некорректный JSON'
};
}
}
const result = parseJsonSafe('{"id": 1, "name": "Пётр"}');
if (result.ok) {
console.log('Пользователь:', result.data.name);
} else {
console.log(result.error);
}
Такой подход удобен: функция не ломает программу, а возвращает предсказуемый результат.
Оператор throw: как создать ошибку вручную
Иногда ошибка не возникает сама, но вы хотите остановить выполнение, потому что данные не соответствуют правилам. Для этого используется throw.
function getDiscount(age) {
if (typeof age !== 'number') {
throw new TypeError('Возраст должен быть числом');
}
if (age < 0) {
throw new RangeError('Возраст не может быть отрицательным');
}
return age >= 18 ? 10 : 5;
}
try {
console.log(getDiscount(-3));
} catch (error) {
console.error(error.name + ': ' + error.message);
}
Совет: бросайте не строки, а объекты ошибок через new Error(), new TypeError(), new RangeError(). Так вы сохраните стек вызовов и сделаете отладку проще.
finally: код, который выполнится всегда
Блок finally выполняется независимо от результата: была ошибка или нет. Он полезен для очистки состояния: убрать индикатор загрузки, разблокировать кнопку, закрыть ресурс.
function submitForm() {
const button = document.querySelector('#submit');
try {
button.disabled = true;
console.log('Отправляем форму...');
// здесь могла бы быть логика отправки
} catch (error) {
console.error('Ошибка отправки:', error.message);
} finally {
button.disabled = false;
console.log('Кнопка снова доступна');
}
}
Даже если внутри try произойдёт сбой, finally всё равно вернёт интерфейс в нормальное состояние.
Собственные классы ошибок
В небольших скриптах достаточно стандартного Error. Но в приложениях удобнее создавать собственные типы ошибок: например, для валидации, авторизации или работы с API.
class ValidationError extends Error {
constructor(message, field) {
super(message);
this.name = 'ValidationError';
this.field = field;
}
}
function createUser(data) {
if (!data.email) {
throw new ValidationError('Email обязателен', 'email');
}
return {
id: Date.now(),
email: data.email
};
}
try {
const user = createUser({ email: '' });
console.log(user);
} catch (error) {
if (error instanceof ValidationError) {
console.log('Ошибка в поле:', error.field);
console.log(error.message);
} else {
console.error('Неизвестная ошибка:', error);
}
}
Так код становится понятнее: вы можете по-разному обрабатывать разные категории ошибок.
Частая ошибка новичков: слишком широкий try...catch
Не стоит оборачивать в try...catch всю программу без необходимости. Так легко скрыть настоящую проблему.
// Плохо: непонятно, где именно произошёл сбой
try {
loadUser();
renderProfile();
initSlider();
sendAnalytics();
} catch (error) {
console.log('Что-то пошло не так');
}
Лучше обрабатывать ошибку там, где вы действительно можете принять решение: повторить действие, показать сообщение, использовать значение по умолчанию.
function getUserName(user) {
try {
return user.profile.name.trim();
} catch (error) {
return 'Гость';
}
}
Но даже этот пример в реальном коде часто лучше решить проверками или optional chaining, если это ожидаемая ситуация, а не исключение.
try...catch и асинхронный код
Важно понимать: обычный try...catch не поймает ошибку, которая возникла позже в callback, например внутри setTimeout.
try {
setTimeout(() => {
throw new Error('Ошибка внутри таймера');
}, 1000);
} catch (error) {
// Этот catch не сработает
console.log('Поймали:', error.message);
}
Ошибка появляется уже после выполнения try. Поэтому обрабатывать её нужно внутри callback:
setTimeout(() => {
try {
throw new Error('Ошибка внутри таймера');
} catch (error) {
console.error('Поймали внутри callback:', error.message);
}
}, 1000);
А при работе с async/await конструкция try...catch снова становится удобной:
async function loadUser() {
try {
const response = await fetch('/api/user');
if (!response.ok) {
throw new Error('Сервер вернул ошибку: ' + response.status);
}
return await response.json();
} catch (error) {
console.error('Не удалось загрузить пользователя:', error.message);
return null;
}
}
Лучшие практики обработки ошибок
- Не глушите ошибки молча. Пустой catch почти всегда плохая идея.
- Показывайте пользователю понятное сообщение, а технические детали оставляйте для логов.
- Используйте throw для невозможных состояний: неверный тип, отсутствующий обязательный параметр, некорректный формат.
- Не используйте исключения для обычной логики, например для проверки каждого элемента массива.
- Создавайте собственные ошибки, если приложение растёт и нужны разные сценарии обработки.
Если вы хотите системно прокачать базу языка — от синтаксиса до уверенной практики с DOM, событиями, асинхронностью и реальными задачами — посмотрите курс «JavaScript с нуля до уровня уверенного разработчика». Он хорошо дополняет такие темы, как обработка ошибок в JavaScript, потому что показывает их в контексте настоящего кода.
Краткий итог
Обработка ошибок в JavaScript try catch нужна, чтобы программа оставалась устойчивой даже при сбоях. Используйте try для опасного кода, catch для реакции, throw для создания ошибок и finally для обязательной очистки. А когда проект становится сложнее, вводите собственные классы ошибок — это делает код понятнее и удобнее в сопровождении.
-
Создано 05.10.2026 17:00:29
-
Михаил Русаков

Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.