Azure Function在失败时自动重试UnhandledPromiseRejectionWarning

时间:2018-11-26 16:37:39

标签: node.js promise azure-functions node-fetch azure-durable-functions

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)
  });

};

我有一个持久函数,可以像上面那样调用一个活动函数。我为此活动功能设置了失败自动重试。要重试该功能,需要获取错误。

所以在获取请求中,当我收到类似404之类的响应时,我想抛出一个错误。但是,当我从catch块扔出时,出现如下错误

  

UnhandledPromiseRejectionWarning:未处理的承诺拒绝。这个   由抛出异步函数引起的错误   没有障碍,或者拒绝了没有处理的承诺   .catch()。

功能在那里暂停并停止执行。我必须手动停止并开始执行。我该如何处理以便函数重试?

2 个答案:

答案 0 :(得分:1)

您的代码分支。

忽略细节,您拥有的是:

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()

在两种情况下,都包括return,则调用方将需要捕获错误,否则您将再次收到未处理的错误警告。

答案 1 :(得分:0)

发现使用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;

};