Ich möchte einige Dinge in meinem JS-Code werfen und ich möchte, dass sie instanceof Error sind, aber ich möchte auch, dass sie etwas anderes sind.
In Python würde man normalerweise die Unterklasse Exception.
Was ist bei JS zu tun?
Ich möchte einige Dinge in meinem JS-Code werfen und ich möchte, dass sie instanceof Error sind, aber ich möchte auch, dass sie etwas anderes sind.
In Python würde man normalerweise die Unterklasse Exception.
Was ist bei JS zu tun?
En 2018 Ich denke, dies ist der beste Weg, der IE9+ und moderne Browser unterstützt.
アップデイト : Siehe dieser Test y Repo zum Vergleich bei verschiedenen Implementierungen.
function CustomError(message) {
Object.defineProperty(this, 'name', {
enumerable: false,
writable: false,
value: 'CustomError'
});
Object.defineProperty(this, 'message', {
enumerable: false,
writable: true,
value: message
});
if (Error.hasOwnProperty('captureStackTrace')) { // V8
Error.captureStackTrace(this, CustomError);
} else {
Object.defineProperty(this, 'stack', {
enumerable: false,
writable: false,
value: (new Error(message)).stack
});
}
}
if (typeof Object.setPrototypeOf === 'function') {
Object.setPrototypeOf(CustomError.prototype, Error.prototype);
} else {
CustomError.prototype = Object.create(Error.prototype, {
constructor: { value: CustomError }
});
}
_Beachten Sie auch, dass __proto__
Eigenschaft ist Abgelehnt die in anderen Antworten weit verbreitet ist._
WICHTIG : Diese Antwort stammt aus dem Jahr 2016 und ist jetzt möglicherweise veraltet. JavaScript im Allgemeinen und Node.js im Besonderen haben sich stark weiterentwickelt und bieten nun mehr Syntaxmöglichkeiten, um die gleichen Ergebnisse zu erzielen. Der folgende Inhalt wird aus historischen Gründen beibehalten und nur für den Fall, dass jemand irgendwo da draußen mit älteren Node.js-Versionen arbeitet.
Ursprüngliche Antwort:
Der Vollständigkeit halber -- nur weil keine der vorherigen Antworten diese Methode erwähnt hat -- wenn Sie mit Node.js arbeiten und sich nicht um die Browserkompatibilität kümmern müssen, ist der gewünschte Effekt ziemlich einfach mit der eingebauten inherits
der util
Modul ( offizielle Dokumente hier ).
Nehmen wir zum Beispiel an, Sie möchten eine benutzerdefinierte Fehlerklasse erstellen, die einen Fehlercode als erstes Argument und die Fehlermeldung als zweites Argument annimmt:
Datei custom-error.js :
'use strict';
var util = require('util');
function CustomError(code, message) {
Error.captureStackTrace(this, CustomError);
this.name = CustomError.name;
this.code = code;
this.message = message;
}
util.inherits(CustomError, Error);
module.exports = CustomError;
Jetzt können Sie Ihr Projekt instanziieren und übergeben/werfen. CustomError
:
var CustomError = require('./path/to/custom-error');
// pass as the first argument to your callback
callback(new CustomError(404, 'Not found!'));
// or, if you are working with try/catch, throw it
throw new CustomError(500, 'Server Error!');
Beachten Sie, dass bei diesem Ausschnitt der Stack-Trace den richtigen Dateinamen und die richtige Zeile enthält und die Fehlerinstanz den richtigen Namen hat!
Dies geschieht durch die Verwendung des captureStackTrace
Methode, die eine stack
Eigenschaft des Zielobjekts (in diesem Fall die CustomError
instanziiert wird). Weitere Einzelheiten zur Funktionsweise finden Sie in der Dokumentation aquí .
Wie einige Leute schon gesagt haben, ist es mit ES6 ziemlich einfach:
class CustomError extends Error { }
Also habe ich das in meiner App ausprobiert (Angular, Typescript) und es hat einfach nicht funktioniert. Nach einiger Zeit habe ich herausgefunden, dass das Problem von Typescript kommt :O
見る https://github.com/Microsoft/TypeScript/issues/13965
Das ist sehr beunruhigend, denn wenn man das tut:
class CustomError extends Error {}
try {
throw new CustomError()
} catch(e) {
if (e instanceof CustomError) {
console.log('Custom error');
} else {
console.log('Basic error');
}
}
In Node oder direkt in Ihrem Browser wird es angezeigt: Custom error
Versuchen Sie, das mit Typescript in Ihrem Projekt auf der Typescript-Spielwiese auszuführen, es wird angezeigt Basic error
...
Die Lösung besteht darin, wie folgt vorzugehen:
class CustomError extends Error {
// we have to do the following because of: https://github.com/Microsoft/TypeScript/issues/13965
// otherwise we cannot use instanceof later to catch a given type
public __proto__: Error;
constructor(message?: string) {
const trueProto = new.target.prototype;
super(message);
this.__proto__ = trueProto;
}
}
Die hoch bewertete Antwort von Crescent Fresh ist irreführend. Obwohl seine Warnungen ungültig sind, gibt es andere Einschränkungen, auf die er nicht eingeht.
Erstens ergibt die Argumentation in Crescents Absatz "Caveats:" keinen Sinn. Die Erklärung impliziert, dass die Programmierung von "a bunch of if (error instanceof MyError) else ..." im Vergleich zu mehreren catch-Anweisungen umständlich oder langatmig ist. Mehrere instanceof-Anweisungen in einem einzigen catch-Block sind genauso prägnant wie mehrere catch-Anweisungen - sauberer und prägnanter Code ohne irgendwelche Tricks. Dies ist eine großartige Möglichkeit, Javas großartige throwable-subtype-spezifische Fehlerbehandlung zu emulieren.
WRT "scheint die Nachricht Eigenschaft der Unterklasse nicht gesetzt werden", das ist nicht der Fall, wenn Sie eine ordnungsgemäß konstruiert Fehler Unterklasse verwenden. Um Ihre eigene ErrorX Error-Unterklasse zu erstellen, kopieren Sie einfach den Codeblock, der mit "var MyError =" beginnt, und ändern Sie das eine Wort "MyError" in "ErrorX". (Wenn Sie Ihrer Unterklasse eigene Methoden hinzufügen möchten, folgen Sie dem Beispieltext).
Die wirkliche und wesentliche Einschränkung der JavaScript-Fehler-Subklassifizierung ist, dass für JavaScript-Implementierungen oder Debugger, die verfolgen und berichten über Stack-Trace und Ort der Instanziierung, wie FireFox, ein Ort in Ihrem eigenen Fehler-Subklassen-Implementierung wird als der Instanziierungspunkt der Klasse aufgezeichnet werden, während, wenn Sie einen direkten Fehler verwendet, wäre es der Ort, wo Sie ausgeführt "new Error(...)"). IE-Benutzer würden dies wahrscheinlich nicht bemerken, aber Benutzer von Fire Bug auf FF werden sehen, dass neben diesen Fehlern nutzlose Dateinamen und Zeilennummern gemeldet werden, und müssen den Stack-Trace bis zu Element 1 aufschlüsseln, um den tatsächlichen Instanzierungspunkt zu finden.
Zusätzlich zum Standard message
Eigenschaft unterstützt JavaScript nun das Hinzufügen spezifischer cause
des Fehlers als optionalen Parameter für die Error
Konstrukteur:
const error1 = new Error('Error one');
const error2 = new Error('Error two', { cause: error1 });
// error2.cause === error1
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.