В чем разница между `throw new Error` и` throw someObject`?

378

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

Когда я сделал, throw new Error('sample')как в следующем коде

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"}в которой я смог получить доступ к свойствам ошибки.

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

Разница, как видно в коде? Как строка будет просто передана как строка, а объект как объекты, но синтаксис будет другим?

Я не исследовал объект ошибки бросания ... Я сделал только бросание строк.

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

Джаяпал Чандран
источник
6
Проблема с throw new Error ({prop: val}) в том, что это недопустимая конструкция Error. Ошибка имеет известные свойства, как обсуждал Хемант.
grantwparks
связанные: Бросать струны вместо Errorс
Берги

Ответы:

216

Вот хорошее объяснение об объекте The Error и ваших собственных ошибках

Объект ошибки

Что мы можем извлечь из него в случае ошибки? Объект Error во всех браузерах поддерживает следующие два свойства:

  • name: имя ошибки или, более конкретно, имя функции-конструктора, к которой относится ошибка.

  • сообщение: описание ошибки, причем это описание зависит от браузера.

Свойство name может возвращать шесть возможных значений, которые, как уже упоминалось, соответствуют именам конструкторов ошибки. Они есть:

Error Name          Description

EvalError           An error in the eval() function has occurred.

RangeError          Out of range number value has occurred.

ReferenceError      An illegal reference has occurred.

SyntaxError         A syntax error within code inside the eval() function has occurred.
                    All other syntax errors are not caught by try/catch/finally, and will
                    trigger the default browser error message associated with the error. 
                    To catch actual syntax errors, you may use the onerror event.

TypeError           An error in the expected variable type has occurred.

URIError            An error when encoding or decoding the URI has occurred 
                   (ie: when calling encodeURI()).

Бросать свои ошибки (исключения)

Вместо того чтобы ждать появления одного из 6 типов ошибок, прежде чем элемент управления будет автоматически перенесен из блока try в блок catch, вы также можете явно генерировать свои собственные исключения, чтобы это происходило по требованию. Это отлично подходит для создания собственных определений того, что является ошибкой, и когда управление должно быть передано в catch.

Хемант Металия
источник
4
о да. это одна хорошая вещь, которую я пропустил, прежде чем задавать этот вопрос. в любом случае, пользователи, которые ищут информацию, связанную с этим, будут очищены. Теперь мне ясно, что к чему. :) Спасибо. я вернусь, чтобы проголосовать через несколько дней.
Джаяпал Чандран
185
Даже не отвечает на вопрос пока самый голосующий голос?
user9993
@ user9993 Пользователь, который задавал вопрос, искал подробного понимания в чате в то время, поэтому соответствующий ответ был предоставлен и полезен для пользователя. это причина для принятия и большинства голосов.
Хемант Металия
5
@HemantMetalia Но он прав, ответ показывает даже малейшую попытку ответить на вопрос ОП, как указано. Если в чате был получен совершенно другой ответ, который должен остаться в чате, то здесь вопрос и ответ не имеют никакой логической связи.
Мёрре
И чтобы ответить на оригинальный вопрос, это не имеет значения для Javascript. Однако Error(и подклассы) используются по соглашению. Они также по умолчанию предоставляют свойство стека, хотя его можно вручную добавить к любому другому. Так что на самом деле это в основном соглашение, на ход программы не влияет то, что вы бросаете, просто то, что вы throwвообще имеете значение. Вы могли бы, throw "grandmother down the stairs";и это будет работать так же, за исключением того, что не будет прикрепленных функций трассировки стека и обработки ошибок, как ожидают репортеры, отладчики Error, или свойств, которые идут вместе, если быть более точным.
Мёрре
104

брось "Я Злой"

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

try {
  throw "I'm Evil"
  console.log("You'll never reach to me", 123465)
} catch (e) {
  console.log(e); //I'm Evil
}

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


выкинуть новую ошибку ("я такая милая")

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

try {
  throw new Error("I'm Evil")
  console.log("You'll never reach to me", 123465)
} catch (e) {
  console.log(e.name, e.message); //Error, I'm Evil
}

Нищит Дханани
источник
16
как насчет различий между «throw Error (« что угодно »)» и «throw new Error (« что угодно »)» - оба работают.
joedotnot
9
Ошибка функциональна, новая Ошибка - конструктор. оба работают одинаково developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Нишит Дханани
5
@NishchitDhanani Я нахожу странным, что такой неразборчивый и неправильный комментарий вызывает отклик. И «ошибка является функциональной», и «новая ошибка - конструктор» не имеют никакого смысла и / или являются ошибочными. В этом контексте неясно, что именно ссылка должна «доказать». Это страница MDN для Error, где связь с комментарием? Половина людей, комментирующих и отвечающих на вопросы ОП, должны были просто молчать.
Мёрре
@ Mörre Смотрите этот раздел Used as a functionпо этой ссылке ... developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Nishchit Dhanani
Хорошо, я понял. Это функция .
Nishchit Dhanani
73

Следующая статья, возможно, более подробно описывает, какой вариант лучше выбрать; 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 (неуверенные в версиях), неправильно сообщают сообщение при использовании первого.

Это может привести к ошибке, но не все браузеры реагируют так, как вы ожидаете. Firefox, Opera и Chrome отображают сообщение «uncaught исключения», а затем включают строку сообщения. Safari и Internet Explorer просто выдают ошибку «необнаруженное исключение» и вообще не предоставляют строку сообщения. Понятно, что это неоптимально с точки зрения отладки.

Ред.
источник
36

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

throw new Error('sample')

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

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

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

Объект ошибки будет иметь свойство «message», которое будет «sample».

IonicBurger
источник
12
Второй действительно работает, но не очень полезным способом. Он выполняет toString()метод для переданного объекта, что приводит [object Object]к ошибке (как написано в Op).
cjn
15

вы можете throwкак объект

throw ({message: 'This Failed'})

тогда, например, в вашем try/catch

try {
//
} catch(e) {
    console.log(e); //{message: 'This Failed'}
    console.log(e.message); //This Failed
}

или просто выбросить строковую ошибку

throw ('Your error')

try {
//
} catch(e) {
    console.log(e); //Your error
}

throw new Error //only accept a string
Mbanda
источник
15

ErrorКонструктор используется для создания объекта ошибки. Объекты ошибок выбрасываются при возникновении ошибок во время выполнения. Объект Error также может использоваться как базовый объект для определенных пользователем исключений.

Определяемые пользователем ошибки генерируются через throwоператор. управление программой будет передано первому catchблоку в стеке вызовов.

Разница между выдачей ошибки с и без объекта Error:


throw {'hehe':'haha'};

В chrome devtools выглядит так:

введите описание изображения здесь

Chrome говорит нам, что у нас есть неперехваченная ошибка, которая просто является объектом JS. Сам объект может иметь информацию об ошибке, но мы до сих пор не знаем, откуда она появилась. Не очень полезно, когда мы работаем над нашим кодом и отлаживаем его.


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

В chrome devtools выглядит так:

введите описание изображения здесь

Ошибка, выдаваемая объектом Error, дает нам трассировку стека при его расширении. Это дает нам ценную информацию, откуда именно произошла ошибка, которая часто является ценной информацией при отладке вашего кода. Также обратите внимание, что в сообщении об ошибке указывается [object Object], что Errorконструктор ожидает строку сообщения в качестве первого аргумента. Когда он получает объект, он приводит его в строку.

Виллем ван дер Веен
источник
2

Реагировать поведение

Помимо остальных ответов, я хотел бы показать одно отличие в React.

Если я брошу a new Error()и я нахожусь в режиме разработки, я получу экран ошибки и журнал консоли. Если я брошу строковый литерал, я увижу его только в консоли и, возможно, пропущу его, если не смотрю журнал консоли.

пример

Выдача сообщения об ошибке в консоль и отображение экрана ошибки в режиме разработки (экран не будет виден в рабочей среде ).

throw new Error("The application could not authenticate.");

Экран ошибки в реакции

Принимая во внимание, что следующий код только входит в консоль:

throw "The application could not authenticate.";
Эль Мак
источник