Throw: примеры (JAVASCRIPT)

Использование throw в JavaScript на практике
Раздел: Обработка ошибок, Исключения
throw(expression (any)): -

Оператор throw

Оператор throw в JavaScript используется для генерации исключительных ситуаций (исключений). В отличие от многих других языков, throw — это оператор, а не функция. Он может применяться в любом месте кода для прерывания нормального выполнения программы и передачи управления ближайшему блоку catch.

Использование оператора:

  • При возникновении ошибок в логике программы
  • Для валидации входных параметров функций
  • При обработке асинхронных операций с ошибками
  • Для создания пользовательских типов ошибок

Синтаксис: throw выражение;

Оператор throw может принимать любое выражение в качестве аргумента. Хотя традиционно принято бросать объекты ошибок (наследники Error), технически можно использовать любые значения: строки, числа, объекты, даже null или undefined.

Оператор не возвращает значение в обычном смысле — его выполнение прерывает текущий поток выполнения. Если исключение не перехватывается блоком catch, программа завершается с ошибкой.

Базовые примеры использования

Различные варианты применения оператора throw:

1. Бросок строки (не рекомендуется на практике)

throw "Произошла ошибка";
Uncaught Произошла ошибка

2. Бросок объекта Error

throw new Error("Стандартная ошибка");
Uncaught Error: Стандартная ошибка

3. Бросок специализированной ошибки

throw new TypeError("Ожидалось число");
Uncaught TypeError: Ожидалось число

4. Бросок с любым значением

throw {code: 404, message: "Не найдено"};
Uncaught {code: 404, message: "Не найдено"}

Похожие механизмы в JavaScript

В JavaScript нет прямых альтернатив оператору throw, но есть связанные механизмы обработки ошибок:

1. Конструкция try...catch...finally

Позволяет перехватывать и обрабатывать исключения, сгенерированные через throw. Используется вместе с throw, а не вместо него.

2. Promise.reject()

Для асинхронного кода, основанного на промисах, метод Promise.reject() создает отклоненный промис, который может быть обработан через .catch(). В асинхронных функциях обычно используется throw внутри, который преобразуется в отклоненный промис.

3. Генерация событий ошибок

В браузерном JavaScript можно генерировать события ошибок через dispatchEvent, но этот подход используется для других целей и не является заменой throw.

Аналоги в других языках программирования

Python: оператор raise

raise ValueError("Некорректное значение")
ValueError: Некорректное значение

Отличие: Python требует использования классов исключений, бросок произвольных значений не рекомендуется.

PHP: оператор throw

throw new Exception('Ошибка в PHP');
Fatal error: Uncaught Exception: Ошибка в PHP

Сходство: синтаксис похож на JavaScript, но в PHP 8.0+ можно бросать только объекты, реализующие интерфейс Throwable.

Java: ключевое слово throw

throw new IOException("Ошибка ввода-вывода");
IOException: Ошибка ввода-вывода

Отличие: Java требует объявления пробрасываемых исключений в сигнатуре метода (ключевое слово throws).

C++: оператор throw

throw std::runtime_error("Ошибка времени выполнения");
terminate called after throwing an instance of 'std::runtime_error'

Особенность: в современном C++ использование исключений имеет больше ограничений и рекомендаций по сравнению с JavaScript.

Типичные ошибки

1. Неперехваченные исключения

function risky() { throw new Error("Опасно!"); }
risky(); // Исключение не перехвачено
Uncaught Error: Опасно!

2. Бросок без new для встроенных ошибок

throw Error("Забыл new"); // Работает, но не рекомендуется
Uncaught Error: Забыл new

3. Потеря контекста при повторном throw

try { throw new Error("Оригинал"); }
catch(e) { throw "Новая строка"; } // Теряется стек оригинальной ошибки
Uncaught Новая строка

4. Бросок в асинхронном коде без обработки

setTimeout(() => { throw new Error("Асинхронная ошибка"); }, 0);
Uncaught Error: Асинхронная ошибка (в консоли браузера)

Изменения в последних версиях

Спецификация ECMAScript не вносила фундаментальных изменений в работу оператора throw в последних версиях. Однако есть связанные улучшения:

  • ES2015 (ES6): введены классы, что упростило создание пользовательских ошибок через наследование от Error.
  • ES2019: улучшена обработка стектрейсов при цепочке исключений, свойство cause для указания причины ошибки.
  • ES2022: ошибки в статических блоках классов теперь генерируются корректно.

Пример с cause (ES2019+):

throw new Error("Внешняя ошибка", {cause: new Error("Внутренняя причина")});

Расширенные примеры

1. Пользовательский класс ошибки

Пример javascript
class ValidationError extends Error {
  constructor(message, field) {
    super(message);
    this.name = "ValidationError";
    this.field = field;
  }
}

function validateUser(user) {
  if (!user.name) throw new ValidationError("Имя обязательно", "name");
  return true;
}

try {
  validateUser({});
} catch(e) {
  console.log(e.name, e.message, e.field);
}
ValidationError Имя обязательно name

2. Использование в асинхронных функциях

Пример javascript
async function fetchData(url) {
  const response = await fetch(url);
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  return response.json();
}

fetchData("https://invalid.url").catch(e => console.log(e.message));
HTTP 404 (или другая ошибка сети)

3. Генерация нескольких типов ошибок

Пример javascript
function parseNumber(input) {
  if (typeof input !== "string") throw new TypeError("Ожидалась строка");
  const num = Number(input);
  if (isNaN(num)) throw new RangeError("Нечисловое значение");
  if (num < 0) throw new Error("Число должно быть положительным");
  return num;
}

4. Повторный throw с сохранением оригинальной ошибки

Пример javascript
try {
  JSON.parse("{invalid json");
} catch(e) {
  throw new Error("Ошибка парсинга конфигурации", {cause: e});
}
Uncaught Error: Ошибка парсинга конфигурации

5. Использование в генераторах

Пример javascript
function* generator() {
  try {
    yield 1;
  } catch(e) {
    console.log("Поймано в генераторе:", e);
  }
  yield 2;
}

const g = generator();
g.next();
g.throw(new Error("Тестовая ошибка"));
console.log(g.next().value);
Поймано в генераторе: Error: Тестовая ошибка
2

JS throw function comments

En
Throw Throws a user-defined exception