Автоматическая повторная попытка функции Azure при сбое UnhandledPromiseRejectionWarning - PullRequest
0 голосов
/ 26 ноября 2018
const fetch = require('node-fetch');
let url = 'something.com';

module.exports = function(context) {
  let a = fetch(url)

  a.then(res => {
    if(res.status!=200) throw new Error(res.statusText)
    else{
      context.done(null, res.body);
    }
  });
  a.catch(err => {
      console.log(err)
      throw new Error(err)
  });

};

У меня есть долговременная функция, которая вызывает функцию активности, как описано выше.Я установил автоматическую повторную попытку при сбое в этой функции активности.Чтобы повторить попытку, функция должна получить ошибку.

Итак, в запросе get я хочу выдать ошибку, когда получаю ответ, например 404 или что-то подобное.Но когда я выбрасываю из блока catch, я получаю сообщение об ошибке, как показано ниже

UnhandledPromiseRejectionWarning: необработанное отклонение обещания.Эта ошибка возникла либо в результате выброса внутри асинхронной функции без блока catch, либо в результате отклонения обещания, которое не было обработано с помощью функции .catch ().

останавливается и останавливает выполнение. Я долженвручную остановить и начать выполнение.Как я могу справиться с этим, чтобы функция повторялась?

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Обнаружено, что при использовании async/await эта проблема исчезает, а функция повторной попытки после исключения выдается.

const fetch = require('node-fetch');
let url = 'something.com';

module.exports = async function(context) {

  let res = await fetch(url)

  if(res.status!=200) throw new Error(res.statusText);
  else return res.body;

};
0 голосов
/ 26 ноября 2018

Ваш код веток.

Не обращая внимания на детали, у вас есть:

let a = <Promise>; // root
a.then(...); // branch_1
a.catch(...); // branch_2

Таким образом, несмотря на то, что вы ловите ошибки, возникающие в a, любая ошибка, возникающая в ветви 1, не будет обработана.Отсюда предупреждение

Сравните это с:

let a = <Promise>; // root
a.then(...).catch(...); // branch

или

<Promise>.then(...).catch(...); // no assignment necessary

Итак, вы можете написать:

module.exports = function(context) {
    return fetch(url)
    .then(res => {
        if(res.status!=200) {
            throw new Error(res.statusText);
        } else {
            context.done(null, res.body);
        }
    })
    .catch(err => {
        console.log(err)
        throw new Error(err)
    });
};

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

module.exports = function(context) {
    return fetch(url)
    .then(res => {
        if(res.status!=200) {
            throw new Error(res.statusText);
        } else {
            return res;
        }
    });
};

... и вызовом .context.done(null, res.body); при .then() обратном вызове в вызывающем абоненте.

Inв обоих случаях, с включенным return, вызывающей стороне нужно будет перехватывать ошибки, в противном случае вы снова получите необработанное предупреждение об ошибке.

...