How to use instanceof in a switch statement

Solution 1:

A good option is to use the constructor property of the object:

// 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);
}

Notice that the constructor must match exactly with the one that object was created (suppose error is an instance of NotAllowedError and NotAllowedError is a subclass of Error):

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

This makes a difference from instanceof, which can match also the super class:

  • error instanceof NotAllowedError is true
  • error instanceof Error is true

Check this interesting post about constructor property.

Solution 2:

Workaround, to avoid if-else. Found here

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);
}

Solution 3:

An alternative to this switch case is to just have a status field in the Error's constructor.

For Example, build your error like so:

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

Handle your error like so:

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