首页 > 解决方案 > Azure Function automatic retry on failure UnhandledPromiseRejectionWarning

问题描述

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

};

I have a durable function that calls an activity function like above. I have set automatic retry on failure on this activity function. To retry the function needs to get an error.

So In get request I want to throw an error when i get response like 404 or something similar. But when i throw from catch block i get an error like below

UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch().

function pauses there and stops execution.I have to manually stop and start the execution. How can i handle this so that the function retries?

标签: node.jspromiseazure-functionsnode-fetchazure-durable-functions

解决方案


你的代码分支。

忽略细节,你所拥有的是:

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包含在内,调用者将需要捕获错误,否则您将再次收到未处理的错误警告。


推荐阅读