Jaka jest różnica między „throw new Error” i „throw someObject”?

378

Chcę napisać typową procedurę obsługi błędów, która będzie łapać niestandardowe błędy zgłaszane celowo w dowolnej instancji kodu.

Kiedy mi się throw new Error('sample')podobało w poniższym kodzie

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

Dziennik pokazuje w przeglądarce Firefox jako Error: [object Object]i nie mogłem przeanalizować obiektu.

Po drugie throwdziennik pokazuje się następująco:Error: hehe

Ale kiedy to zrobiłem

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

konsola pokazała jako: Object { hehe="haha"}w której mogłem uzyskać dostęp do właściwości błędu.

Jaka jest różnica?

Czy różnica wynika z kodu? Jak ciąg zostanie przekazany jako ciąg, a obiekt jako obiekt, ale składnia będzie inna?

Nie badałem rzucania obiektu błędu… Zrobiłem tylko rzucanie strun.

Czy istnieje inny sposób niż wyżej wymienione dwie metody?

Jayapal Chandran
źródło
6
Problem z rzucaniem nowego błędu ({prop: val}) polega na tym, że nie jest to poprawna konstrukcja błędu. Błąd ma znane właściwości omówione przez Hemanta.
grantwparks

Odpowiedzi:

216

Oto dobre wyjaśnienie dotyczące obiektu Błąd i zgłaszania własnych błędów

Obiekt błędu

Co możemy z niego wyciągnąć w przypadku błędu? Obiekt Error we wszystkich przeglądarkach obsługuje następujące dwie właściwości:

  • name: nazwa błędu, a dokładniej nazwa funkcji konstruktora, do której należy błąd.

  • komunikat: opis błędu, przy czym opis ten różni się w zależności od przeglądarki.

Sześć możliwych wartości może zostać zwróconych przez właściwość name, która, jak wspomniano, odpowiada nazwom konstruktorów błędu. Oni są:

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()).

Zgłaszanie własnych błędów (wyjątki)

Zamiast czekać na wystąpienie jednego z 6 rodzajów błędów, zanim kontrola zostanie automatycznie przeniesiona z bloku try do bloku catch, możesz również jawnie wprowadzić własne wyjątki, aby wymusić to na żądanie. Jest to świetne do tworzenia własnych definicji błędów i kiedy należy przekazać kontrolę, aby ją złapać.

Hemant Metalia
źródło
4
o tak. to jedna dobra rzecz, którą przegapiłem przed zadaniem tego pytania. w każdym razie użytkownicy szukający informacji związanych z tym zostaną usunięte. Teraz nie mam pojęcia, co jest. :) Dziękuję Ci. wrócę do głosowania za kilka dni.
Jayapal Chandran
184
Czy nawet nie odpowiada na pytanie, które jest najbardziej pozytywną odpowiedzią?
user9993
@ user9993 Użytkownik, który zadał pytanie, szukał szczegółowego zrozumienia na czacie w tym czasie, więc odpowiednio udzielono odpowiedzi i był użyteczny dla użytkownika. to jest powód akceptacji i większości głosów.
Hemant Metalia
5
@HemantMetalia Ale ma rację, odpowiedź nie pokazuje nawet najmniejszej próby odpowiedzi na pytanie OP, jak stwierdzono. Jeśli na czacie została udzielona inna odpowiedź, która powinna pozostać na czacie, tutaj pytania i odpowiedzi nie mają żadnego logicznego związku.
Mörre
Aby odpowiedzieć na pierwotne pytanie, JavaScript nie ma znaczenia. Jednak Error(i podklasy) są używane przez konwencję. Domyślnie zapewniają również właściwość stosu, chociaż można ją ręcznie dodać do dowolnej innej. Tak naprawdę jest to w większości konwencja, na to, co rzucasz, nie ma wpływu na przebieg programu, tylko że throwwe wszystkich sprawach. Mógłbyś throw "grandmother down the stairs";i to działałoby tak samo, z tym wyjątkiem, że nie będzie dołączonych funkcji śledzenia stosu i obsługi błędów, reporterzy, debuggery Errorlub właściwości, które są dostarczane, by być bardziej precyzyjne.
Mörre
104

rzuć „I'm Evil”

throwbędzie zakończyć dalsze wykonanie i wystawiać wiadomość ciąg na połów błąd.

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

Konsola po rzucie nigdy nie zostanie osiągnięta z powodu zakończenia.


wyślij nowy błąd („Jestem taki słodki”)

throw new Errorujawnia zdarzenie błędu z nazwą i komunikatem dwóch parametrów . To także kończy dalsze wykonywanie

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
}

Nishchit Dhanani
źródło
16
co z różnicą między „wyrzuć błąd („ cokolwiek ”)” i „wyrzuć nowy błąd („ cokolwiek ”)” - oba działają.
joedotnot
9
Błąd działa, nowy Błąd jest konstruktorem. oba działają tak samo developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Nishchit Dhanani
5
@NishchitDhanani Wydaje mi się dziwne, że taki nieczytelny i zły komentarz zyskuje poparcie. Zarówno „Błąd działa”, ani „nowy Błąd jest konstruktorem” nie ma żadnego sensu i / lub jest błędny. W tym kontekście nie jest jasne, co dokładnie link ma „udowodnić”. To strona MDN Error, w porządku, gdzie jest połączenie z komentarzem? Połowa osób komentujących i odpowiadających na pytania PO powinna była milczeć.
Mörre
@ Mörre Zobacz tę sekcję Used as a functionz tego linku ... developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Nishchit Dhanani
OK, rozumiem To funkcja .
Nishchit Dhanani,
73

Poniższy artykuł może bardziej szczegółowo wyjaśnia, który z nich jest lepszym wyborem; throw 'An error'lub throw new Error('An error'):

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

Sugeruje to, że ten drugi ( new Error()) jest bardziej niezawodny, ponieważ przeglądarki takie jak Internet Explorer i Safari (niepewne wersji) nie zgłaszają poprawnie komunikatu podczas korzystania z pierwszego.

Spowoduje to wygenerowanie błędu, ale nie wszystkie przeglądarki reagują w oczekiwany sposób. Firefox, Opera i Chrome wyświetlają komunikat „nieprzechwycony wyjątek”, a następnie zawierają ciąg komunikatu. Safari i Internet Explorer po prostu zgłaszają błąd „nieprzechwyconego wyjątku” i w ogóle nie dostarczają ciągu komunikatów. Oczywiście jest to nieoptymalne z punktu widzenia debugowania.

Ed.
źródło
36

Najpierw wspomnij o tym kodzie:

throw new Error('sample')

a następnie w pierwszym przykładzie piszesz:

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

Pierwszy obiekt Error faktycznie działałby, ponieważ oczekuje wartości ciągu, w tym przypadku „próbki”. Drugi nie zrobiłby tego, ponieważ próbujesz przekazać obiekt i oczekuje on ciągu.

Obiekt błędu miałby właściwość „message”, która byłaby „sample”.

IonicBurger
źródło
12
Drugi działa, ale nie w bardzo użyteczny sposób. Wykonuje toString()metodę na przekazanym obiekcie, co powoduje [object Object]błąd (jak napisał Op).
cjn
15

możesz throwjako przedmiot

throw ({message: 'This Failed'})

wtedy na przykład w twoim try/catch

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

lub po prostu wyrzuć błąd ciągu

throw ('Your error')

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

throw new Error //only accept a string
Mbanda
źródło
15

The ErrorKonstruktor służy do utworzenia obiektu błędu. Obiekty błędów są zgłaszane, gdy wystąpią błędy w czasie wykonywania. Obiekt Error może być również używany jako obiekt podstawowy dla wyjątków zdefiniowanych przez użytkownika.

Błędy zdefiniowane przez użytkownika są zgłaszane przez throwinstrukcję. kontrola programu zostanie przekazana do pierwszego catchbloku na stosie wywołań.

Różnica między zgłaszaniem błędu zi bez obiektu błędu:


throw {'hehe':'haha'};

W chrome devtools wygląda następująco:

wprowadź opis zdjęcia tutaj

Chrome informuje nas, że mamy nieprzechwycony błąd, który jest po prostu obiektem JS. Sam obiekt może zawierać informacje dotyczące błędu, ale nadal nie wiemy od razu, skąd się wziął. Niezbyt przydatne, gdy pracujemy nad naszym kodem i debugujemy go.


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

W chrome devtools wygląda następująco:

wprowadź opis zdjęcia tutaj

Błąd zgłaszany przez obiekt Error daje nam ślad stosu, gdy go rozwijamy. Daje nam to cenne informacje, z których dokładnie pochodzi błąd, które często są cennymi informacjami podczas debugowania kodu. Zwróć też uwagę, że błąd mówi [object Object], że to dlatego, że Errorkonstruktor oczekuje ciągu komunikatu jako pierwszego argumentu. Gdy otrzyma obiekt, zmusi go do utworzenia łańcucha.

Willem van der Veen
źródło
2

Reaguj zachowanie

Oprócz pozostałych odpowiedzi, chciałbym pokazać jedną różnicę w React.

Jeśli rzucę a new Error()i będę w trybie programowania, otrzymam ekran błędu i dziennik konsoli. Jeśli rzucę literał ciąg znaków, zobaczę go tylko w konsoli i być może przegapię, jeśli nie oglądam logu konsoli.

Przykład

Zgłoszenie błędu rejestruje się w konsoli i wyświetla ekran błędu w trybie programowania (ekran nie będzie widoczny w środowisku produkcyjnym).

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

Ekran błędu w reakcji

Podczas gdy następujący kod loguje się tylko do konsoli:

throw "The application could not authenticate.";
El Mac
źródło