Содержание
В JavaScript есть удобная конструкция try..catch, позволяющая обрабатывать ошибки (исключения). Используется он чаще для тех кусков кода, где важен точный результат и ошибки нужно выводить и контролировать. Например такую конструкцию мне нужно было использовать в проекте Свой личный кабинет для интернет — магазина на Тильда
Ниже разберём, как движок ищет обработчик ошибки, что попадает в catch
, зачем нужен finally
, как писать «правильный» лог и почему try/catch
в асинхронных конструкциях спасает от трудно-уловимых сбоев. Всё это проиллюстрируем фрагментом из рабочей функции автопересчёта корзины.
Что такое исключение и как оно работает
Исключением (exception) называют любое «ненормальное» событие, из-за которого текущая точка выполнения не может продолжить работу.
Если интерпретатор сталкивается с «встроенной» ошибкой (ReferenceError
, TypeError
, кастомная Error
), он создаёт объект ошибки и начинает «подниматься» по стеку вызовов, пока не найдёт ближайший catch
.
Если ни один обработчик не перехватит исключение, оно дойдёт до корневого контекста:
Такой «вывал» почти всегда считается критической ситуацией: приложение может остаться в неопределённом состоянии.
Базовый синтаксис
try {
// код, который может «рвануть»
}
catch (error) {
// здесь мы «гасим пожар»
}
finally {
// выполняется В ЛЮБОМ СЛУЧАЕ
}
Блок finally
необязателен, но полезен для закрытия соединений, очистки таймеров, скрытия лоадеров и т. д.
Объект Error
чем он полезен:
Свойство | Что в нём | Зачем нужно |
---|---|---|
name | Тип (Error , TypeError , SyntaxError ,…) | Быстро фильтровать категории ошибок |
message | Человеко-читаемое описание | Показывать юзеру или писать в лог |
stack | Строка со стеком вызовов | Точная точка сбоя + путь до неё |
try/catch
и асинхронность: подводные камни
Только синхронные исключения ловятся напрямую.
Ошибки, случившиеся «позднее» — в колбэке setTimeout
, внутри промиса, в async
-функции — требуют отдельного catch
(или .catch()
у промиса).
В нашем коде startAutoRecalculation
таймер синхронный (setInterval
), а вот его тело с try/catch
исполняется асинхронно каждые 200 мс. Поэтому «защитный купол» нужен внутри колбэка, иначе случайная ошибка в пересчётах зальёт консоль «красным» и прекратит повторную логику.
Разбираем пример по строчкам
let autoRecalcTimer = null; // ⏳ Хранит таймер
function startAutoRecalculation(deliveryDiscount = null, deliveryTypes = []) {
if (autoRecalcTimer) clearInterval(autoRecalcTimer); // ✅ Если таймер уже есть — сбрасываем
console.log("✅ [ШАГ 1] Запуск постоянного обновления корзины...");
autoRecalcTimer = setInterval(() => {
if (typeof tcart === "undefined") return;
try {
if (tcart.promocode && tcart.promocode.message === "OK") {
console.log("✅ Промокод активен, пересчитываем скидку...");
recalculateTildaCart();
// ???? Добавляем повторное применение скидки на доставку
if (lastAppliedPromocode && lastAppliedPromocode.promocode_d_discount) {
applyDeliveryDiscount(
lastAppliedPromocode.promocode_d_discount,
lastAppliedPromocode.promocode_d_type
);
}
}
} catch (error) {
console.error("❌ [КРИТИЧЕСКАЯ ОШИБКА] Ошибка в `startAutoRecalculation`:", error);
}
}, 200);
}
Что даёт такое обёртывание:
⛔️ Ошибка внутри recalculateTildaCart
не обрушит цикл setInterval
, т. е. корзина продолжит попытки пересчитаться.
Мы получаем полный стек и можем отладить баг.
В критичных случаях кодером легко добавить аварийное восстановление (сбросить промокод, выключить таймер, показать фолбэк-UI).
Рекомендации по правильному catch
Делайте | Не делайте |
---|---|
Ловите только те ошибки, которые можете обработать осмысленно. | Не оборачивайте огромные куски кода «на всякий случай» — потеряете точку падения. |
Логируйте error.stack , error.message и любые контекстные данные (ID корзины, userId). | Не оставляйте catch (e) {} пустым — «глушители» превращают баги в призраков. |
При «частичном» восстановлении возвращайте безопасное значение. | Не злоупотребляйте «мутировавшим» глобальным состоянием в catch — можете создать ещё больше хаоса. |
Для необрабатываемых сбоёв — throw дальше или отправляйте на мониторинг. | Не полагайтесь на try/catch для управления обычным потоком (контроль версий, branching logic). |
finally
: гарантированная уборка
try {
startTransaction();
doStuff();
} catch (e) {
rollback();
throw e; // репроброс
} finally {
closeConnection(); // вызовется ВСЕГДА
}
Блок выполняется после try
и/или catch
, даже если там return
, throw
или ранний выход по ошибке.
В async
-функциях он тоже работает, но дожидается завершения await
-ов внутри try
.
Вывод
try … catch
останавливает «каскадную вспышку» ошибок, позволяя приложению остаться живым.
В асинхронных сценариях ставьте его внутрь колбэков/async
-функций, иначе исключения «утекут».
Всегда логируйте стек + контекст, различайте «восстановление» и «репроброс».
Используйте finally
для гарантированной очистки ресурсов.
Не прячьте баги — ловите ровно те ошибки, которые способны обработать.
Понимание этих принципов делает функцию startAutoRecalculation
(и любой другой сложный механизм) устойчивой к неожиданным «падениям», а ваш дебаг — быстрым и предсказуемым.
Как со мной связаться
Если вы не нашли для себя ответ в моих статьях или у вас есть задача, присылайте ваше ТЗ задание под ваш проект.
Пишите https://t.me/vbalakin буду рад помочь с доработкой.
Еще материалы
-
6 Switch case в JavaScript + Tilda
Зачем вообще switch Когда вариантов развития событий больше двух-трёх, цепочкаif … else if … else if … быстро превращается в
-
5 Условие if \ else в JavaScript + Tilda
Разбираем условные конструкции if, else и тернарный оператор в JavaScript для Tilda: наглядные примеры, готовый код и практические советы по оптимизации.
-
4 Арифметические операции и нюансы преобразований текста в числа и наоборот JS Tilda
К чему такой простой вопрос затронут? А все элементарно, часто при работе с расчетом скидок и промокодов для своих кастомных
-
3 Как объявлять переменные и функции JS в Тильде, чтобы не было проблем
Мы уже привыкли, что можем создавать свой JS код и называть внутри него переменные и функции, так как нам нужно.
-
2. Как логировать промежуточные результаты и еще console.log JS + Tilda
Вот бывает такое, все вроде бы должно работать, а не работает. Сам часто сталкиваюсь с ситуацией когда код написан, проверен
-
1. Как лучше добавлять JS в Тильда
Благодаря веку информационных технологий, мы можем делать все что угодно и как угодно, поэтому любые ваши действия будут правильными, просто