Избегайте попадания в два разных блока `.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];
});