Ошибки и try...catch
Программа не всегда может выполнить то, о чём её просят: данные пришли в неверном формате, сервер не ответил, нужного значения нет. Когда возникает ошибка, выполнение останавливается, и всё, что записано после, не выполняется. Конструкция try...catch позволяет перехватить ошибку и продолжить работу.
try и catch
Код, в котором может возникнуть ошибка, помещают в блок try. Если ошибка случилась, выполнение сразу переходит в блок catch:
try {
JSON.parse('это не JSON');
} catch (error) {
console.log('Не удалось разобрать данные'); // Не удалось разобрать данные
}Функция JSON.parse() не смогла разобрать строку и выбросила ошибку. Без try...catch программа на этом бы остановилась. Если ошибки нет, блок catch просто пропускается.
Объект ошибки
В скобках после catch указывают переменную — в неё попадает объект с описанием ошибки. Его свойство name содержит вид ошибки, а message — текст:
try {
undefinedFunction();
} catch (error) {
console.log(error.name); // ReferenceError
console.log(error.message); // undefinedFunction is not defined
}Встроенные типы ошибок
По имени ошибки можно понять, что пошло не так. Вот те, что встречаются чаще всего:
| Тип | Когда возникает |
|---|---|
ReferenceError | обращение к необъявленной переменной |
TypeError | действие не подходит для значения: вызов не функции, свойство у undefined |
SyntaxError | код или JSON написаны с ошибкой |
RangeError | число вне допустимого диапазона |
try {
const user = undefined;
user.name;
} catch (error) {
console.log(error.name); // TypeError
}throw
Оператор throw выбрасывает ошибку самостоятельно. Так функция сообщает, что не может выполнить свою работу. Ошибку создают через new Error('текст'):
function divide(a, b) {
if (b === 0) {
throw new Error('Делить на ноль нельзя');
}
return a / b;
}
try {
console.log(divide(10, 2)); // 5
console.log(divide(1, 0));
} catch (error) {
console.log(error.message); // Делить на ноль нельзя
}Первый вызов сработал, второй выбросил ошибку, и управление перешло в catch — второй console.log так и не выполнился.
finally
Блок finally выполняется всегда — и после успешного try, и после catch. В нём завершают начатое: скрывают индикатор загрузки, закрывают файл или соединение:
try {
console.log('Загружаем данные');
throw new Error('Сбой сети');
} catch (error) {
console.log(error.message);
} finally {
console.log('Загрузка завершена');
}
// Загружаем данные
// Сбой сети
// Загрузка завершенаЧастая ошибка
Пустой блок catch «проглатывает» ошибку: программа продолжает работать с неверными данными, а найти причину потом очень трудно.
try {
JSON.parse('{ сломано }');
} catch (error) {
// пусто: об ошибке никто не узнает
}Перехватывайте только те ошибки, которые умеете обработать. Если обработать нельзя, хотя бы выведите сообщение через console.error(error).