Ich versuche, Fehler mit ES6 und Babel zu erweitern. Es klappt nicht.
class MyError extends Error {
constructor(m) {
super(m);
}
}
var error = new Error("ll");
var myerror = new MyError("ll");
console.log(error.message) //shows up correctly
console.log(myerror.message) //shows empty string
Das Fehlerobjekt erhält nie den richtigen Nachrichtensatz.
Versuchen Sie es in Babel REPL .
Jetzt habe ich einige Lösungen für SO gesehen ( zum Beispiel hier ), aber alle scheinen sehr un-ES6-y zu sein. Wie geht das auf eine schöne ES6-Art? (Das funktioniert in Babel)
javascript
ecmascript-6
babeljs
transpiler
Karel Bílek
quelle
quelle
Antworten:
Basierend auf der Antwort von Karel Bílek würde ich eine kleine Änderung an Folgendem vornehmen
constructor
:Dies wird
MyError
im Stapel gedruckt und nicht im generischenError
.Außerdem wird die Fehlermeldung zum Stack-Trace hinzugefügt, der in Karels Beispiel fehlte.
Es wird auch verwendet,
captureStackTrace
wenn es verfügbar ist.Mit Babel 6 benötigen Sie transform-builtin-extens ( npm ), damit dies funktioniert.
quelle
if (typeof Error.captureStackTrace === 'function') { Error.captureStackTrace(this, this.constructor.name) } else { this.stack = (new Error(message)).stack; }
. Ich würde argumentieren, dass es besser ist, diese Funktion zu verwenden, wenn sie verfügbar ist, da sie einen "nativeren" Aufrufstapel bietet und den Namen des Fehlerobjekts druckt. Wenn Sie dies natürlich auch nur auf der Serverseite (Node) verwenden, ist dies natürlich auch kein Problem.this.stack = (new Error(message)).stack
Sie das bekommen ... aber in der Praxis ist dies wahrscheinlich keine große Sache.new MyError('foo') instanceof MyError === false
extendable-error-class
vorkompiliert : npmjs.com/package/extendable-error-class, was praktisch ist, um eine Abhängigkeit von babel-plugin-transform-builtin-this.message = message;
ist überflüssig mitsuper(message);
Durch die Kombination dieser Antwort , dieser Antwort und dieses Codes habe ich diese kleine "Helfer" -Klasse erstellt, die anscheinend gut funktioniert.
Versuchen Sie es in REPL
quelle
this.stack = (new Error(message)).stack;
- Andernfalls fehlt die Nachricht im Stacktracemessage
im Fehlerstapelkonstruktor hinzugefügt wird , so dass es die richtige Meldung oben im Stapel anzeigt, wenn es geworfen wird:this.stack = (new Error(message)).stack;
myerror.name
gibt jetzt "Fehler" zurück. Ich bin mir nicht sicher, ob dies mit späteren Versionen von babel zusammenhängt. Siehe @ sukimas Antwort untenUm dies endlich zur Ruhe zu bringen. In Babel 6 wird ausdrücklich darauf hingewiesen, dass die Entwickler das Erweitern von integrierten Funktionen nicht unterstützen . Obwohl dieser Trick bei Dingen wie usw. nicht hilfreich
Map
istSet
, funktioniert erError
. Dies ist wichtig, da eine der Kernideen einer Sprache, die eine Ausnahme auslösen kann, darin besteht, benutzerdefinierte Fehler zuzulassen. Dies ist doppelt wichtig, da Versprechen nützlicher werden, da sie einen Fehler ablehnen sollen .Die traurige Wahrheit ist, dass Sie dies in ES2015 immer noch auf die alte Weise durchführen müssen.
Beispiel in Babel REPL
Benutzerdefiniertes Fehlermuster
Auf der anderen Seite gibt es ein Plugin für Babel 6, um dies zu ermöglichen.
https://www.npmjs.com/package/babel-plugin-transform-builtin-extend
Update: (Stand: 29.09.2016) Nach einigen Tests scheint es, dass babel.io nicht alle Asserts ordnungsgemäß berücksichtigt (ausgehend von einem benutzerdefinierten erweiterten Fehler). In Ember.JS funktioniert das Erweitern von Error jedoch wie erwartet: https://ember-twiddle.com/d88555a6f408174df0a4c8e0fd6b27ce
quelle
Error.toString()
. Die Notwendigkeit, spezielle Reifen und Drehungen durchzuführen, um dies zu erreichen, bedeutet, dass die meisten Entwickler dies vermeiden und auf schlechte Praktiken wie das Werfen von Strings anstelle von Fehlern zurückgreifen. Oder ihre eigene Karte wie Objekte erstellen. Warum müssen solche OOP-Methoden abgeschreckt werden?Bearbeiten : Änderungen in Typescript 2.1 brechen
Das Bearbeiten der ursprünglichen Antwort von Lee Benson funktioniert für mich ein wenig. Dadurch werden der Instanz auch
stack
zusätzlicheExtendableError
Klassenmethoden hinzugefügt.quelle
Object.setPrototypeOf
denMyError
Konstruktor aufrufen . stackoverflow.com/a/41102306/186334 github.com/Microsoft/TypeScript-wiki/blob/master/…Mit den neuesten Änderungen in Babel 6 finde ich, dass Transform-Built-Extend nicht mehr funktioniert. Am Ende habe ich diesen gemischten Ansatz gewählt:
und
Als Ergebnis bestehen alle diese Tests:
quelle
Zitieren
Obwohl der oben genannte Codes nicht ausgeben kann der Stack - Trace , wenn nicht
this.stack = (new Error()).stack;
oderError.captureStackTrace(this, this.constructor.name);
in aufgerufen Babel . IMO, es ist vielleicht ein Problem hier.Tatsächlich kann der Stack-Trace unter
Chrome console
undNode.js v4.2.1
mit diesen Code-Snippets ausgegeben werden .Ausgabe von
Chrome console
.Ausgabe von
Node.js
quelle
Zusätzlich zur @ zangw-Antwort können Sie Ihre Fehler folgendermaßen definieren:
das wirft korrekten Namen, Nachricht und Stacktrace:
quelle
new MyError('foo') instanceof MyError === false
.Node.js v7.7.3
.Das
class MyError extends Error {…}
Syntax ist korrekt.Beachten Sie, dass Transpiler immer noch Probleme beim Erben von integrierten Objekten haben. In deinem Fall,
scheint das Problem zu beheben.
quelle
Error.call()
gibt eine neue Fehlerinstanz für mich zurück.In Anbetracht dessen, dass die akzeptierte Antwort nicht mehr funktioniert, können Sie immer eine Fabrik als Alternative verwenden ( Repl ):
quelle
Ich bevorzuge eine stärkere Syntax als oben beschrieben. Zusätzliche Methoden bei Fehlertyp helfen Ihnen dabei, hübsche
console.log
oder etwas anderes zu erstellen .Um diesen Code zu testen, können Sie etwas Ähnliches ausführen:
Eine Erweiterung des
CustomError
Typs ist willkommen. Es ist möglich, dem erweiterten Typ bestimmte Funktionen hinzuzufügen oder vorhandene zu überschreiben. Beispielsweise.quelle
Wie @sukima erwähnt, können Sie native JS nicht erweitern. Die Frage des OP kann nicht beantwortet werden.
Ähnlich wie bei der Antwort von Melbourne2991 habe ich eher eine Fabrik verwendet, aber die Empfehlung von MDN für Kundenfehlertypen befolgt .
quelle
Das funktioniert bei mir:
quelle
Ohne Babel, aber in einfachem ES6, scheint Folgendes für mich gut zu funktionieren:
Testen von REPL:
Wie Sie sehen können, enthält der Stapel sowohl den Fehlernamen als auch die Meldung. Ich bin mir nicht sicher, ob mir etwas fehlt, aber alle anderen Antworten scheinen die Dinge zu komplizieren.
quelle
Ich habe die Lösung von @Lee Benson folgendermaßen ein wenig verbessert:
extensableError.js
ein Beispiel für einen Fehler
Anschließend können Sie Fehler gruppieren, während Sie über Optionsspezifizierer verfügen, um zu entscheiden, was in einigen anwendungsspezifischen Situationen anders zu tun ist
quelle