webentwicklung-frage-antwort-db.com.de

Verwendung von instanceof in einer switch-Anweisung

Ich verwende benutzerdefinierte Fehler ( es6-error ), die es mir ermöglichen, Fehler basierend auf ihrer Klasse wie folgt zu behandeln:

import { DatabaseEntryNotFoundError, NotAllowedError } from 'customError';

function fooRoute(req, res) {
  doSomethingAsync()
    .then(() => {
      // on resolve / success
      return res.send(200);
    })
    .catch((error) => {
      // on reject / failure
      if (error instanceof DatabaseEntryNotFoundError) {
        return res.send(404);
      } else if (error instanceof NotAllowedError) {
        return res.send(400);
      }
      log('Failed to do something async with an unspecified error: ', error);
      return res.send(500);
    };
}

Jetzt würde ich lieber einen Schalter für diese Art von Strömung verwenden, was zu folgendem Ergebnis führt:

import { DatabaseEntryNotFoundError, NotAllowedError } from 'customError';

function fooRoute(req, res) {
  doSomethingAsync()
    .then(() => {
      // on resolve / success
      return res.send(200);
    })
    .catch((error) => {
      // on reject / failure
      switch (error instanceof) {
        case NotAllowedError:
          return res.send(400);
        case DatabaseEntryNotFoundError:
          return res.send(404);
        default:
          log('Failed to do something async with an unspecified error: ', error);
          return res.send(500);
      }
    });
}

instanceof funktioniert jedoch nicht so. Letzteres versagt also.

Gibt es eine Möglichkeit, eine Instanz auf ihre Klasse in einer switch-Anweisung zu überprüfen?

31
AlexTes

Eine gute Option ist die Verwendung der constructorproperty des Objekts:

// on reject / failure
switch (error.constructor) {
    case NotAllowedError:
        return res.send(400);
    case DatabaseEntryNotFoundError:
        return res.send(404);
    default:
        log('Failed to do something async with an unspecified error: ', error);
        return res.send(500);
}

Beachten Sie, dass constructor genau mit dem übereinstimmen muss, von dem das Objekt erstellt wurde (angenommen, error ist eine Instanz von NotAllowedError und NotAllowedError ist eine Unterklasse von Error):

  • error.constructor === NotAllowedError ist true 
  • error.constructor === Error ist false

Dies unterscheidet sich von instanceof, die auch der Superklasse entsprechen kann: 

  • error instanceof NotAllowedError ist true
  • error instanceof Error ist true

Überprüfen Sie diesen interessanten Beitrag über constructor-Eigenschaft.

65
Dmitri Pavlutin

Problemumgehung, um zu vermeiden, wenn-sonst. Gefunden hier

switch (true) {
    case error instanceof NotAllowedError: 
        return res.send(400);

    case error instanceof DatabaseEntryNotFoundError: 
        return res.send(404);

    default:
        log('Failed to do something async with an unspecified error: ', error);
        return res.send(500);
}
3
ya_dimon

Eine Alternative zu diesem Schalterfall besteht darin, nur ein Statusfeld im Konstruktor des Fehlers zu haben. 

Erstellen Sie beispielsweise Ihren Fehler wie folgt:

class NotAllowedError extends Error {
    constructor(message, status) {
        super(message);
        this.message = message;
        this.status = 403; // Forbidden error code
    }
}

Behandeln Sie Ihren Fehler so:

.catch((error) => {
  res.send(error.status);
});
0
Lachlan Young