Избегайте попадания в два разных блока `.catch` в Promise

С bluebird, скажем, я хочу поймать ошибку и выдать другую ошибку.

DAO.getById('AccessTokens', token).then(function(matchingToken) {
  return matchingToken;
}).catch(NotFoundError, function(err) {
  Logging.error("caught a not found error"); // or some kind of logger...
  throw err;
}).catch(function(err) {
  throw ['DB Error - Tokens', err];
});

Если я запускаю это и выдается NotFoundError, я вижу, что запускается обработчик NotFoundError, затем запускается универсальный обработчик ошибок. Я хотел бы, чтобы только обработчик NotFoundError запускался / распространялся для NotFoundError.

Есть ли способ перехватить некоторые ошибки и распространить их, не затрагивая обработчик ошибок catchall?

Я мог бы удалить ловушку, но тогда возможно распространение неизвестных ошибок. Я мог бы проверить NotFoundErrors в перехвате, но это похоже на дублированное поведение... есть ли другой вариант?

1 ответ

Нет, но давайте поговорим о том, почему

В настоящее время - нет, это рассматривалось в прошлом, но случай использования был недостаточно убедителен в данный момент. Петка Горги и я обсудили это в IRC в какой-то момент и в целом согласились, что используя .catch(function(){ (поймать все) не самая лучшая идея - не зная, что может произойти сбой, проблематично, и, как правило, если вы терпите неудачу по неизвестной вам причине, - вы хотите перезагрузить сервер, так как неясно, как вы будете восстанавливаться.

Лично я бы просто удалил ловушку - особенно потому, что она генерирует что-то, что не является ошибкой (так что нет трассировки стека, что проблематично и в любом случае ухудшается с точки зрения отладки). Вы можете регистрировать ошибки глобально и корректно завершать работу.

Я взрослый человек, а ты не мой начальник

Хорошо, ты прав. Библиотека склонна к тому, что я считаю хорошей практикой обработки ошибок. Ваше мнение может отличаться, и вы можете написать всеобъемлющее, как вы хотите. К сожалению, я писал код на Haskell весь день, так что это может показаться немного функциональным по стилю - вы всегда можете просто поймать типы в универсальном:

function typeT(type){
    return function(item){ return item instanceof type; };
}
function not(fn){
    return function(){ return !(fn.apply(this, arguments); };
}

DAO.getById('AccessTokens', token).then(function(matchingToken) {
  return matchingToken;
}).catch(NotFoundError, function(err) {
  Logging.error("caught a not found error"); // or some kind of logger...
  throw err;
}).catch(not(typeT(NotFoundError)), function(err) { // predicate function catch clause
  throw ['DB Error - Tokens', err];
});
Другие вопросы по тегам