Может ли ESLint помочь вам предотвратить отказ от невыполненных обещаний?

Есть ли у eslint возможность предупреждать о местах, где можно предотвратить отказ от несанкционированных обещаний?

Необработанные отклонения обещаний устарели. В будущем необработанные отклонения обещаний завершат процесс Node.js с ненулевым кодом выхода. - DEP0018

Знаете что, мне нравится, как движок в настоящее время обрабатывает Unhandled-Promise-Rejection; потому что, когда у вас есть Unhandled-Promise-Rejection, вместо сбоя всей службы служба продолжает работать, и только часть, которая зависела от экземпляра ошибочного обещания, не может быть завершена. Допустим, ошибка была вызвана неким пользовательским вводом, которого программист не ожидал во время проверки. Сама асинхронная функция, у которой было исключение, продолжает обслуживать другие вызовы (те, которые не имеют такого же непредвиденного ввода пользователя). Да, на данный момент в программе есть мусор в виде вечно ожидающих ожиданий, которые никогда не разрешаются, но для меня это более надежно, чем допускать полный сбой службы.

В любом случае, я полагаю, кто-то уже решил, что совершенство важнее надежности.

Поэтому мне пора сделать мой код уродливым и совершенным, имея .catch(()=>{}); добавлен вскоре после всех этих ожиданий в моем коде, который раньше выглядел чистым, как MOP&GLOW.

Предлагает ли ESlint что-нибудь, чтобы помочь мне найти бесполезные обещания? Есть ли какие-то дополнения к спецификациям, которые находятся в разработке, для устранения этого уродства и неудобств?

Лично мне хотелось бы настроить механизм так, чтобы он просто завершал код, который находится в цепочке обещаний из UnhandledPromiseRejection. Я определенно хотел бы решить эту проблему проще, чем добавлять все эти.catch(()=>{}) ко всем моим ожидаемым вызовам асинхронных функций.

2 ответа

Решение

Сам ESLint не имеет той функциональности, которую вы ищете, но есть очень популярный плагин eslint-plugin-prom.

В частности, правило " поймай или верни" делает то, о чем вы просите:

Убедитесь, что каждый раз, когда к обещанию применяется then(), также применяется catch(). Если вы возвращаете это обещание, делаются исключения.

Действительный

myPromise.then(doSomething).catch(errors)
myPromise
  .then(doSomething)
  .then(doSomethingElse)
  .catch(errors)
function doSomethingElse() {
  return myPromise.then(doSomething)
}

Инвалид

myPromise.then(doSomething)
myPromise.then(doSomething, catchErrors) // catch() may be a little better
function doSomethingElse() {
  return myPromise.then(doSomething)
}

Интересно, почему никто не упомянул правило "Никаких плавающих обещаний" из "typescript-eslint" - https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-floating-promises.md Наверное, это стоит назвать "Никаких невыполненных обещаний".:)

Перенос вашего кода для использования async/awaitвместо цепочек обещаний поможет начать и снова сделает ваш код красивее; есть codemod, который может вам в этом помочь.

В любом случае, я полагаю, кто-то уже решил, что совершенство важнее надежности.

Новое поведение более разумно, если вы спросите меня (особенно при использовании async/await, где .catch(() => ...) просто обычный catch (e) { ... }, и не ловя исключений, ну...)

Если вы используете .then() синтаксис, затем добавив .catch(() => {}) сигнализирует читателю, что вы явно не заботитесь о возникающих ошибках.