Как использовать instanceof в инструкции switch
Я использую пользовательские ошибки (es6-error), позволяя обрабатывать ошибки на основе их класса следующим образом:
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);
};
}
Теперь я бы предпочел использовать переключатель для этого типа потока, в результате чего-то вроде:
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 не работает. Таким образом, последний терпит неудачу.
Есть ли способ проверить экземпляр для его класса в инструкции switch?
Ответы
Ответ 1
Хорошим вариантом является использование свойства constructor
объекта:
// 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);
}
Обратите внимание, что constructor
должен точно совпадать с тем, что был создан объект (предположим, что error
является экземпляром NotAllowedError
и NotAllowedError
является подклассом error
):
-
error.constructor === NotAllowedError
true
-
error.constructor === Error
false
Это отличается от instanceof
, что может соответствовать супер классу:
-
error instanceof NotAllowedError
true
-
error instanceof Error
true
Отметьте этот интересный пост о свойстве constructor
.
Ответ 2
Альтернативой этому случаю переключения является наличие поля состояния в конструкторе ошибок.
Например, создайте свою ошибку следующим образом:
class NotAllowedError extends Error {
constructor(message, status) {
super(message);
this.message = message;
this.status = 403; // Forbidden error code
}
}
Обработайте вашу ошибку следующим образом:
.catch((error) => {
res.send(error.status);
});
Ответ 3
Обходной путь, чтобы избежать if-else. Нашел здесь
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);
}