it-swarm.com.de

prüfung auf Fehlerart in JS

In JS scheint es nicht möglich zu sein zu prüfen, ob ein an eine Funktion übergebenes Argument tatsächlich den Typ 'error' oder eine Instanz von Error hat.

Dies ist zum Beispiel nicht gültig:

typeof err === 'error'

da es nur 6 mögliche Typen gibt (in Form von Strings):

Der Operator typeof gibt die Typinformationen als Zeichenfolge zurück. Es gibt sechs mögliche Werte, die typeof zurückgibt:

"number", "string", "boolean", "object", "function" und "undefined".

MSDN

Was aber, wenn ich einen einfachen Anwendungsfall wie diesen habe:

function errorHandler(err) {

    if (typeof err === 'error') {
        throw err;
    }
    else {
        console.error('Unexpectedly, no error was passed to error handler. But here is the message:',err);
    }
}

was ist also der beste Weg, um festzustellen, ob ein Argument eine Instanz von Error ist?

ist der instanceof-Operator einer beliebigen Hilfe?

88
Alexander Mills

Sie können den Operator instanceof verwenden.

var myError = new Error('foo');
myError instanceof Error // true
var myString = "Whatever";
myString instanceof Error // false
152
Trott

Ich stellte die ursprüngliche Frage - @ Trott's Antwort ist sicherlich die beste.

Da JS jedoch eine dynamische Sprache ist und es so viele JS-Laufzeitumgebungen gibt, kann der Operator instanceof vor allem in der Front-End-Entwicklung scheitern, wenn Grenzen wie z. B. Iframes überschritten werden. Siehe: https://github.com/mrdoob/three.js/issues/5886

Wenn du mit Duck-Typing einverstanden bist, sollte dies gut sein:

let isError = function(e){
 return e && e.stack && e.message;
}

Ich persönlich bevorzuge statisch typisierte Sprachen, aber wenn Sie eine dynamische Sprache verwenden, sollten Sie eine dynamische Sprache für das, was sie ist, annehmen, anstatt sie zu zwingen, sich wie eine statisch typisierte Sprache zu verhalten.

wenn Sie etwas genauer werden wollten, können Sie Folgendes tun:

   let isError = function(e){
     return e && e.stack && e.message && typeof e.stack === 'string' 
            && typeof e.message === 'string';
    }
17
Alexander Mills
var myError = new Error('foo');
myError instanceof Error // true
var myString = "Whatever";
myString instanceof Error // false

Das einzige Problem dabei ist 

myError instanceof Object // true

Eine Alternative dazu wäre die Verwendung der Konstruktoreigenschaft.

myError.constructor === Object // false
myError.constructor === String // false
myError.constructor === Boolean // false
myError.constructor === Symbol // false
myError.constructor === Function // false
myError.constructor === Error // true

Es sei jedoch darauf hingewiesen, dass diese Übereinstimmung sehr spezifisch ist, zum Beispiel:

myError.constructor === TypeError // false
2
Tom

Mit obj.constructor.name können Sie die "Klasse" eines Objekts überprüfen. Https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Function_names_in_classes

Zum Beispiel

var error = new Error("ValidationError");
console.log(error.constructor.name);

In der obigen Zeile wird "Error" protokolliert, der Klassenname des Objekts. Dies kann für alle Klassen in Javascript verwendet werden, wenn die Klasse keine Eigenschaft verwendet, die den Namen "Name" trägt. 

0
KimboKast

Oder verwenden Sie dies für verschiedene Arten von Fehlern

function isError(val) {
  return (!!val && typeof val === 'object')
    && ((Object.prototype.toString.call(val) === '[object Error]')
      || (typeof val.message === 'string' && typeof val.name === 'string'))
}
0
Chris