Яка різниця між `кинути нову помилку` та` кинути якийсь об'єкт`?


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
Проблема з помилкою викидання нової помилки ({prop: val}) полягає в тому, що це неправдива конструкція помилки. Помилка має відомі властивості, про які розповідав Hemant.
grantwparks

Відповіді:


216

Ось гарне пояснення щодо об'єкта Помилка та викидання власних помилок

Об'єкт помилки

Тільки, що ми можемо витягти з нього у випадку помилки? Об'єкт 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 типів помилок до автоматичного перенесення з блоку спробу в блок вилову, ви також можете явно викинути власні винятки, щоб змусити це статися на вимогу. Це відмінно підходить для створення власних визначень, що таке помилка, і коли контроль слід передати, щоб знайти.


4
о, так. це один хороший матеріал, який я пропустив, перш ніж задати це питання. все одно користувачі, які шукають інформацію, пов’язану з цим, будуть очищені. Тепер мені зрозуміло, що є що. :) Дякую. я повернусь до голосування через кілька днів.
Джаяпал Чандран

184
Навіть не дає відповіді на запитання, поки найбільш відповідна відповідь?
user9993

@ user9993 Запитаний користувачем запит шукав детальне розуміння відповідно до чату, тому відповідь була надана та корисна для користувача. це причина для прийнятих та більшості голосів.
Hemant Metalia

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
як щодо різниці між "кинути помилку (" що завгодно ")" і "кинути нову помилку (" що завгодно ")" - обидва працюють.
joedotnot

9
Помилка функціональна, нова помилка - конструктор. обидва працює той же розробник.mozilla.org
en-US/docs/Web/JavaScript/Reference/…

5
@NishchitDhanani Мені здається дивним, що такий нерозбірливий і неправильний коментар викликає відгуки. І "Помилка функціональна", ні "нова помилка є конструктором" взагалі не мають сенсу і / або помиляються. У цьому контексті незрозуміло, що саме посилання повинно "доводитися". Це сторінка MDN Error, добре, де зв’язок із коментарем? Половина людей, коментуючи та відповідаючи на питання ОП, просто мусила мовчати.
Mörre

@ 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 відображають повідомлення про "неприхований виняток", а потім включають рядок повідомлення. Safari та Internet Explorer просто кидають помилку "неприхованого винятку" і взагалі не надають рядок повідомлень. Зрозуміло, що це є неоптимальним з точки зору налагодження.


36

Ви вперше згадуєте цей код:

throw new Error('sample')

а потім у своєму першому прикладі ви пишете:

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

Перший об’єкт Помилка насправді спрацює, оскільки він очікує значення рядка, в даному випадку "зразок". Другий не тому, що ви намагаєтесь передати об’єкт, і він очікує рядок.

Об'єкт помилки мав би властивість "message", яке було б "зразок".


12
Другий працює, тільки не дуже корисним чином. Він виконує toString()метод на переданому об'єкті, що призводить [object Object]до помилки (як написав Оп).
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

15

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

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

Різниця між видачею помилки з об'єктом Error та без нього:


throw {'hehe':'haha'};

У хромованих розробниках виглядає так:

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

Chrome повідомляє нам, що у нас є неприхована помилка, яка просто є об'єктом JS. Сам об’єкт може містити інформацію щодо помилки, але ми все ще не знаємо одразу, звідки вона прийшла. Не дуже корисно, коли ми працюємо над своїм кодом і налагоджуємо його.


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

У хромованих розробниках виглядає так:

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

Помилка, передана об'єктом Error, дає нам слід стека, коли ми розгортаємо його. Це дає нам цінну інформацію, звідки точно виникла помилка, яка часто є цінною інформацією при налагодженні коду. Далі зауважте, що помилка говорить [object Object], це тому, щоError конструктор очікує рядок повідомлення в якості першого аргументу. Коли він отримує об'єкт, він примушує його до рядка.


2

Реакція поведінки

Окрім решти відповідей, я хотів би показати одну різницю в React.

Якщо я кину а new Error()та я перебуваю в режимі розробки, я отримаю екран помилок та журнал консолі. Якщо я кину рядковий літерал, я побачу його лише в консолі і, можливо, пропущу його, якщо я не переглядаю журнал консолі.

Приклад

Закидання помилки входить у консоль і показує екран помилки під час роботи в режимі розробки (екран не буде видно у виробництві).

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

Екран помилок у реакції

Беручи до уваги, що наступний код лише входить у консоль:

throw "The application could not authenticate.";
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.