6

Какова разница между `throw new Error` и `throw someObject`?

22

Я хочу написать общий обработчик ошибок, который будет перехватывать кастомные ошибки, выбрасываемые намеренно в любом месте кода.

Когда я выполнил следующий код:

try {
    throw new Error({'hehe':'haha'});
    // throw new Error('hehe');
} catch(e) {
    alert(e);
    console.log(e);
}

Лог в Firefox показывает: Error: [object Object], и я не смог разобрать объект.

Для второго варианта с throw лог показывает: Error: hehe.

Однако, когда я выполнил следующий код:

try {
    throw ({'hehe':'haha'});
} catch(e) {
    alert(e);
    console.log(e);
}

Консоль показала: Object { hehe="haha"}, благодаря чему я смог получить доступ к свойствам ошибки.

В чем разница?

Разница действительно заключается в том, что в первом случае я выбрасываю объект ошибки, а во втором — просто объект? В первом случае строка просто передается как строка, а объект — как объект, но синтаксис отличается?

Я не исследовал, как выбрасывать объект ошибки... Я использовал только выброс строк.

Есть ли другие способы, кроме вышеупомянутых двух?

5 ответ(ов)

3

throw "I'm Evil"

Использование throw прервёт дальнейшее выполнение и передаст строку сообщения при поймании ошибки.

try {
  throw "I'm Evil"
  console.log("Вы никогда не дойдете до меня", 123465)
} catch (e) {
  console.log(e); // I'm Evil
}

Консоль после throw никогда не будет достигнута из-за прерывания выполнения.


throw new Error("I'm Evil")

Использование throw new Error создает событие ошибки с двумя параметрами: name и message. Это также прерывает дальнейшее выполнение.

try {
  throw new Error("I'm Evil")
  console.log("Вы никогда не дойдете до меня", 123465)
} catch (e) {
  console.log(e.name, e.message); // Error I'm Evil
}

throw Error("I'm Evil")

И для полноты картины, этот вариант тоже работает, хотя технически это не самый правильный способ:

try {
  throw Error("I'm Evil")
  console.log("Вы никогда не дойдете до меня", 123465)
} catch (e) {
  console.log(e.name, e.message); // Error I'm Evil
}

console.log(typeof(new Error("hello"))); // object
console.log(typeof(Error)); // function

Таким образом, использование throw может быть разным, в зависимости от ваших целей и контекста. Рекомендуется использовать throw new Error, так как это предоставляет больше информации о возникшей ошибке.

0

Возможно, следующая статья более подробно рассматривает вопрос о том, что лучше использовать: throw 'An error' или throw new Error('An error'):

http://www.nczonline.net/blog/2009/03/10/the-art-of-throwing-javascript-errors-part-2/

В статье утверждается, что использование new Error() более надежно, так как такие браузеры, как Internet Explorer и Safari (неясно, для каких версий), не корректно отображают сообщение об ошибке при использовании первого варианта.

В статье говорится:

Если использовать throw 'An error', это приведет к выбросу ошибки, но не все браузеры будут работать так, как вы ожидаете. Firefox, Opera и Chrome отображают сообщение об "необработанном исключении" и включают строку с сообщением. Safari и Internet Explorer просто выбрасывают ошибку "необработанное исключение" и не предоставляют строку с сообщением вообще. Явно, это не оптимально с точки зрения отладки.

Таким образом, в контексте отладки и кросс-браузерной совместимости, рекомендуется использовать throw new Error().

0

TLDR: Они эквивалентны: Error(x) === new Error(x).

// Это:
const x = Error('Я создан с помощью вызова функции!');
// Имеет такую же функциональность, как и это:
const y = new Error('Я сконструирован через ключевое слово "new"!');

Источник: MDN Web Docs

throw и throw Error функционально эквивалентны. Однако, когда вы их ловите и сериализуете с помощью console.log, они сериализуются не совсем одинаково:

throw 'Параметр не является числом!';
throw new Error('Параметр не является числом!');
throw Error('Параметр не является числом!');

Console.log(e) для приведённого выше кода выдаст 2 разных результата:

Параметр не является числом!
Error: Параметр не является числом!
Error: Параметр не является числом!

Таким образом, хотя поведение Error и new Error идентично, обработка и отображение этих значений при выбросе ошибки может выглядеть по-разному.

0

Вы сначала упоминаете этот код:

throw new Error('sample');

а затем в вашем первом примере пишете:

throw new Error({'hehe':'haha'});

Первый объект ошибки действительно будет полезен, потому что он ожидает строковое значение, в данном случае 'sample'. Второй пример не будет полезен, поскольку вы пытаетесь передать объект, а он ожидает строку, что не позволит отобразить удачное сообщение об ошибке.

В объекте ошибки будет свойство "message", которое будет равно 'sample'.

0

Вы можете использовать конструкцию throw для выброса объектов, как показано ниже:

throw ({message: 'Это не удалось'})

Тогда, например, в вашем блоке try/catch:

try {
    // Ваш код
} catch(e) {
    console.log(e); // {message: 'Это не удалось'}
    console.log(e.message); // Это не удалось
}

Также вы можете просто выбросить строковое сообщение об ошибке:

throw ('Ваша ошибка')

try {
    // Ваш код
} catch(e) {
    console.log(e); // Ваша ошибка
}

А если вы хотите использовать стандартный класс ошибки, вы можете сделать так:

throw new Error('Сообщение об ошибке'); // принимает только строку

Обратите внимание, что при вызове new Error необходимо передавать строку в качестве аргумента.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь