Was ist der Unterschied zwischen "throw new Error" und "throw someObject"?

378

Ich möchte einen allgemeinen Fehlerbehandler schreiben, der benutzerdefinierte Fehler abfängt, die absichtlich in jeder Instanz des Codes ausgelöst werden.

Als ich throw new Error('sample')im folgenden Code mochte

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

Das Protokoll wird in Firefox als angezeigt Error: [object Object]und ich konnte das Objekt nicht analysieren.

Für die Sekunde throwzeigt das Protokoll Folgendes:Error: hehe

Während als ich tat

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

Die Konsole zeigte Folgendes an: Object { hehe="haha"}in dem ich auf die Fehlereigenschaften zugreifen konnte.

Was ist der Unterschied?

Ist der Unterschied im Code zu sehen? Wie String wird nur als String und Objekt als Objekte übergeben, aber die Syntax wird anders sein?

Ich habe das Werfen von Fehlerobjekten nicht untersucht. Ich habe nur Zeichenfolgen geworfen.

Gibt es einen anderen Weg als die beiden oben genannten Methoden?

Jayapal Chandran
quelle
6
Das Problem beim Auslösen eines neuen Fehlers ({prop: val}) ist, dass dies keine gültige Konstruktion des Fehlers ist. Der Fehler hat bekannte Eigenschaften, wie von Hemant diskutiert.
Grantwparks
Verwandte: Strings werfen statt Errors
Bergi

Antworten:

216

Hier ist eine gute Erklärung zum Fehlerobjekt und zum Auslösen eigener Fehler

Das Fehlerobjekt

Was können wir im Fehlerfall daraus extrahieren? Das Fehlerobjekt in allen Browsern unterstützt die folgenden zwei Eigenschaften:

  • name: Der Name des Fehlers oder genauer gesagt der Name der Konstruktorfunktion, zu der der Fehler gehört.

  • message: Eine Beschreibung des Fehlers, wobei diese Beschreibung je nach Browser variiert.

Von der Eigenschaft name können sechs mögliche Werte zurückgegeben werden, die wie erwähnt den Namen der Konstruktoren des Fehlers entsprechen. Sie sind:

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

Wirf deine eigenen Fehler (Ausnahmen)

Anstatt darauf zu warten, dass einer der 6 Fehlertypen auftritt, bevor die Steuerung automatisch vom try-Block zum catch-Block übertragen wird, können Sie auch explizit Ihre eigenen Ausnahmen auslösen, um dies bei Bedarf zu erzwingen. Dies ist ideal, um eigene Definitionen zu erstellen, was ein Fehler ist und wann die Kontrolle auf catch übertragen werden soll.

Hemant Metalia
quelle
4
Oh ja. Dies ist ein gutes Zeug, das ich verpasst habe, bevor ich diese Frage gestellt habe. Auf jeden Fall werden die Benutzer, die nach diesbezüglichen Informationen suchen, gelöscht. Jetzt ist mir klar, was was ist. :) Vielen Dank. Ich werde in ein paar Tagen zurück sein, um abzustimmen.
Jayapal Chandran
184
Beantwortet die Frage noch nicht einmal die am besten bewertete Antwort?
user9993
@ user9993 Der Benutzer, der die Frage gestellt hat, suchte nach einem detaillierten Verständnis gemäß dem Chat zu diesem Zeitpunkt, daher wurde dem Benutzer eine entsprechende Antwort gegeben, die nützlich ist. Das ist der Grund für akzeptierte und die meisten Stimmen.
Hemant Metalia
5
@HemantMetalia Aber er hat Recht, die Antwort zeigt nicht den geringsten Versuch, die Frage des OP wie angegeben zu beantworten. Wenn im Chat eine ganz andere Antwort beantwortet wurde, die im Chat bleiben sollte, haben Frage und Antwort hier keinerlei logische Verbindung.
Mörre
Und um die ursprüngliche Frage zu beantworten, spielt es für Javascript keine Rolle. Jedoch Errorsind (und Subklassen) vereinbarungsgemäß verwendet. Sie bieten auch standardmäßig eine Stapeleigenschaft, die jedoch manuell zu jeder anderen hinzugefügt werden kann. Es ist also meistens Konvention, der Programmfluss wird nicht durch das beeinflusst, was Sie werfen, nur dass Sie throwüberhaupt wichtig sind. Sie könnten throw "grandmother down the stairs";und es würde genauso funktionieren, außer dass es keine angehängten Stack-Trace- und Fehlerbehandlungsfunktionen gibt, die Reporter, Debugger erwarten Error, oder die damit verbundenen Eigenschaften, um genauer zu sein.
Mörre
104

werfen "Ich bin böse"

throwwird beendet die weitere Ausführung & Nachrichtenkette auf belichten Fang den Fehler.

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

Konsole nach Wurf wird wegen Kündigung nie erreicht.


neuen Fehler werfen ("Ich bin so süß")

throw new Errorsetzt ein Fehlerereignis mit zwei params Namen & Nachricht . Es beendet auch die weitere Ausführung

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
quelle
16
Was ist mit dem Unterschied zwischen "Fehler werfen ('was auch immer')" und "neuen Fehler werfen ('was auch immer')" - beide funktionieren.
Joedotnot
9
Fehler ist funktionsfähig, neuer Fehler ist ein Konstruktor. beide funktionieren gleich developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Nishchit Dhanani
5
@NishchitDhanani Ich finde es seltsam, dass solch ein nicht entzifferbarer und falscher Kommentar positive Stimmen bekommt. Sowohl "Fehler ist funktionsfähig" noch "Neuer Fehler ist ein Konstruktor" machen überhaupt keinen Sinn und / oder sind falsch. In diesem Zusammenhang ist unklar, was genau der Link "beweisen" soll. Es ist die MDN-Seite für Error, okay, wo ist die Verbindung zum Kommentar? Die Hälfte der Leute, die OP-Fragen kommentieren und beantworten, hätte einfach schweigen sollen.
Mörre
@ Mörre Siehe diesen Abschnitt Used as a functionvon diesem Link ... developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Nishchit Dhanani
Ich hab es verstanden. Es ist eine Funktion .
Nishchit Dhanani
73

Der folgende Artikel geht vielleicht näher darauf ein, welche die bessere Wahl ist. throw 'An error'oder throw new Error('An error'):

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

Dies deutet darauf hin, dass Letzteres ( new Error()) zuverlässiger ist, da Browser wie Internet Explorer und Safari (unsichere Versionen) die Nachricht bei Verwendung des ersteren nicht korrekt melden.

Wenn Sie dies tun, wird ein Fehler ausgegeben, aber nicht alle Browser reagieren wie erwartet. Firefox, Opera und Chrome zeigen jeweils eine Meldung "Nicht erfasste Ausnahme" an und fügen dann die Nachrichtenzeichenfolge hinzu. Safari und Internet Explorer lösen einfach den Fehler "Nicht erfasste Ausnahme" aus und geben die Nachrichtenzeichenfolge überhaupt nicht an. Dies ist aus Debugging-Sicht eindeutig nicht optimal.

Ed.
quelle
36

Sie erwähnen zuerst diesen Code:

throw new Error('sample')

und dann schreiben Sie in Ihrem ersten Beispiel:

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

Das erste Fehlerobjekt würde tatsächlich funktionieren, da es einen Zeichenfolgenwert erwartet, in diesem Fall 'sample'. Das zweite würde nicht, weil Sie versuchen, ein Objekt zu übergeben, und es erwartet eine Zeichenfolge.

Das Fehlerobjekt hätte die Eigenschaft "message", die "sample" wäre.

IonicBurger
quelle
12
Der zweite funktioniert, nur nicht sehr nützlich. Es führt die toString()Methode für das übergebene Objekt aus, was [object Object]zu dem Fehler führt (wie der Op geschrieben hat).
cjn
15

Sie können throwals Objekt

throw ({message: 'This Failed'})

dann zum Beispiel in Ihrem try/catch

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

oder werfen Sie einfach einen String-Fehler

throw ('Your error')

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

throw new Error //only accept a string
Mbanda
quelle
15

Der ErrorKonstruktor wird verwendet, um ein Fehlerobjekt zu erstellen. Fehlerobjekte werden ausgelöst, wenn Laufzeitfehler auftreten. Das Fehlerobjekt kann auch als Basisobjekt für benutzerdefinierte Ausnahmen verwendet werden.

Benutzerdefinierte Fehler werden über die throwAnweisung ausgelöst . Die Programmsteuerung wird an den ersten catchBlock im Aufrufstapel übergeben.

Der Unterschied zwischen dem Auslösen eines Fehlers mit und ohne Fehlerobjekt:


throw {'hehe':'haha'};

In Chrome sieht devtools so aus:

Geben Sie hier die Bildbeschreibung ein

Chrome teilt uns mit, dass ein nicht erfasster Fehler vorliegt, bei dem es sich nur um ein JS-Objekt handelt. Das Objekt selbst könnte Informationen über den Fehler enthalten, aber wir wissen immer noch nicht sofort, woher er stammt. Nicht sehr nützlich, wenn wir an unserem Code arbeiten und ihn debuggen.


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

In Chrome sieht devtools so aus:

Geben Sie hier die Bildbeschreibung ein

Ein Fehler, der mit dem Fehlerobjekt ausgelöst wird, gibt uns eine Stapelverfolgung, wenn wir es erweitern. Dies gibt uns wertvolle Informationen, von denen der Fehler genau stammt. Dies sind häufig wertvolle Informationen beim Debuggen Ihres Codes. Beachten Sie außerdem, dass der Fehler besagt [object Object], dass der ErrorKonstruktor eine Nachrichtenzeichenfolge als erstes Argument erwartet. Wenn es ein Objekt empfängt, wird es zu einer Zeichenfolge gezwungen.

Willem van der Veen
quelle
2

Verhalten reagieren

Abgesehen von den restlichen Antworten möchte ich einen Unterschied in React zeigen.

Wenn ich a werfe new Error()und mich im Entwicklungsmodus befinde, erhalte ich einen Fehlerbildschirm und ein Konsolenprotokoll. Wenn ich ein String-Literal werfe, sehe ich es nur in der Konsole und vermisse es möglicherweise, wenn ich das Konsolenprotokoll nicht beobachte.

Beispiel

Das Auslösen eines Fehlers meldet sich in der Konsole an und zeigt im Entwicklungsmodus einen Fehlerbildschirm an (der Bildschirm wird in der Produktion nicht angezeigt).

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

Fehlerbildschirm reagiert

Der folgende Code meldet sich nur bei der Konsole an:

throw "The application could not authenticate.";
El Mac
quelle