Я не хочу набирать .catch для каждого обещания, которое я использую. Без этого ошибки, вызванные обещаниями, в высшей степени бесполезны.
Использование целой библиотеки, такой как bluebird, исключительно для этой цели, вызывает у меня дискомфорт.
2 ответа
Для отслеживания ошибок во время разработки в V8 (последние версии Node.js и Chrome) уже есть unhandledRejection
(Node.js) и unhandledrejection
(Chrome) прослушиватель событий по умолчанию, что приводит к предупреждению UnhandledPromiseRejectionWarning
в Node.js и ошибке Uncaught (in promise)
в Chrome.
В предупреждении об устаревании в Node 7 указано, что это будет изменено в будущих версиях Node.js:
Необработанные отклонения обещаний устарели. В будущем необработанные отклонения обещаний завершат процесс Node.js с ненулевым кодом выхода.
Обработка ошибок в обещаниях не является необязательной и должна рассматриваться наравне с try...catch
. Каждое обещание, которое может быть отклонено, должно быть связано с catch
. А в случае async...await
или co
.catch
идентичен try...catch
.
Если предполагается, что ошибка игнорируется, ее нужно перехватить явно. Если обработка ошибок должна быть согласованной во всем приложении и соответствовать уровням журнала, это может быть предусмотрено конструкцией. Например. с обычным пакетом debug
:
const debug = require('debug');
function catchFn(err, ns = 'myapp:caughtPromises') {
debug(ns)(err);
}
function catchPromise(promise, ns) {
promise.catch(err => catchFn(err, ns));
return promise;
}
...
try {
await promise;
} catch (err) {
catchFn(err);
}
// or
catchPromise(promise);
// or
promise.catch(catchFn);
catchFn
также можно расширить для использования сторонней службы ведения журнала.
.catch()
на более высоком уровне, поэтому отказ не остается без внимания. Мне кажется, что они жалуются на то, как трудно определить, где было исходное отклонение, без использования трассировки стека в чем-то вроде Bluebird.
unhandledRejection
, говорит сам за себя. Похоже, что у обещаний нет catch
на более высоком уровне, потому что в этом случае слушатель неприменим. Если в первую очередь вопрос касается правильной трассировки стека, он был сформулирован неправильно (и в этом случае я бы предложил просто придерживаться BB и не изобретать велосипед, особенно для Node).
--no-warnings
, Promise.reject();
будет выдавать предупреждение UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): undefined
как на узле 6, так и на узле 7. Я не уверен, есть ли другие условия, которые могут подавить вывод предупреждений. Опуская catch
. это то же самое, что и пропустить `try ... catch. Это также то, что подразумевает сообщение об устаревании - оно вызовет исключение в следующем Node. Конечно, вы можете опустить передовые методы и перехватить все исключения в глобальном масштабе, но предлагать такой подход в ответе просто неправильно.
Добавьте в свой процесс обработчика необработанных отказов. Вы можете обработать их один раз таким образом, вместо того, чтобы постоянно копировать и вставлять операторы .catch.
process.on( 'unhandledRejection', ( error, promise ) => {
console.log( 'UPR: ' + promise + ' with ' + error )
console.log( error.stack )
} )
.catch(fnErr)
не требует больших усилий, чтобы напечатать ...
unhandledRejection
может быть разумным способом отслеживать необработанные отказы, которые не были обнаружены надзором. Но вот в чем проблема. error
фактически является отклонением, а не обязательно экземпляром Error
. Хотя это хорошая привычка - throw new Error
, если отклонение означает ошибку, error
может быть любым и пропустить свойство stack
. Итак, вот мы - ошибка, которую вовремя не обработал неосторожный разработчик, неожиданно возникает из-за отсутствия стека вызовов (а также вызывает исключение, потому что error
не является объектом).
Похожие вопросы
Новые вопросы
javascript
По вопросам программирования на ECMAScript (JavaScript/JS) и его различных диалектах/реализациях (кроме ActionScript). Имейте в виду, что JavaScript — это НЕ то же самое, что Java! Включите все ярлыки, относящиеся к вашему вопросу; например, [node.js], [jQuery], [JSON], [ReactJS], [angular], [ember.js], [vue.js], [typescript], [svelte] и т. д.
catch
ошибок в конце цепочки. Кроме того, что вы подразумеваете под «глотанием»? Если вы хотите предотвратить это, что должно произойти с ошибками?.catch(function(e) {…})
, которое везде одинаково. Где началась ваша многочисленная сеть? Обработчики событий, обработчики маршрутов? Затем определите функцию-оболочку, которая устанавливает обработчик и соответствующим образом обрабатывает возвращенные обещания. Если бы вы могли опубликовать свой код, я бы смог написать более конкретный ответ..catch()
- это просто плохой код. Вы не можете глобально диагностировать отсутствующие обработчики брака. Просто не так писать хороший код. Необязательно ставить.catch()
на каждое обещание. У вас должен быть один в каждой цепочке обещаний, поскольку я объясняю логику в своем ответе. Если вы проголосовали против моего ответа, я прошу прощения за то, что дал вам правильный программный ответ на вашу ситуацию. Вы не можете сделать это так, как просите, поэтому я описал, как вам следует поступать с отказами. Если тебе это не нравится, я могу удалить свой ответ.