Функция, вызывающая себя в контексте ожидания / обещания - не может деструктурировать свойство «response» из «undefined» или «null».в Eval - PullRequest
0 голосов
/ 24 июня 2019

Я не понимаю ошибку, которую я получаю, и не могу выполнить некоторые "обещанные" действия в javascript.

В сущности, я хотел бы реализовать сторонний API следующим образом:

  • Я звоню в API (см. PollApi)

  • , если время истекает в течение 60 секунд, я получаю журнал, сообщающий мне, что время истекло: ЭТО РАБОТАЕТ

  • если я получаю ответ 500, я перезапускаю вызов (только один раз)

  • Если я получаю 429 (слишком много одновременных вызовов), янужно подождать 10 секунд, затем повторить один и тот же вызов (столько раз, сколько необходимо, пока я не получу 429)

Сценарий работает, когда я совершаю всего несколько вызовов (чтото есть, когда нет одновременных вызовов), но как только у меня есть параллельные вызовы (код 429), то обработка этого сценария в моем коде НЕ РАБОТАЕТ.И ошибка, которую я продолжаю получать, исходит из глобального улова:

[CURL] Rejected because non 200: 429 body: You're sending requests a bit too fast! Please slow down your requests

Faced with error 429 (all available slots on API within the authorized nb of concurrent calls) : retrying in 10 seconds...

TypeError: Cannot destructure property `response` of 'undefined' or 'null'. at eval

Интересно, что выполнение, похоже, НИКОГДА не вводит if ( response ) { log("body is ", body);, который я примерно поставил в начале, чтобы проверить, что происходит.

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

script.js

 const handler = ErrorHandlingHOF(async function(event, context, callback) {
   try {
    const THIRDPARTY_API_RETRY_INTERVAL_ON_429 = 10 * 1000;
    const THIRDPARTY_REQUEST_TIMEOUT = 60 * 1000;
    let timerId;    
    let revisited = {};

    let { response, body } = await runUrlOnThirdPartyApi(url);    
    let json;
    if ( response ) {
      log("body is ", body);
      json = JSON.parse(body);              
      log('runUrlOnThirdPartyApi(url) gives us : ', json);
    } 

    function pollApi(url) {
      return new Promise(function(resolve, reject) {
         let timeout = false;
         curl(url).then(function({ response, body }) {
           if (!timeout) {
             resolve({response, body})
           }
         }).catch(reject);
         setTimeout(function() {
           timeout = true;
           reject(new Error("Request to URL ", url, " timed out"))
         }, THIRDPARTY_REQUEST_TIMEOUT)
       });
     }

    function runUrlOnThirdPartyApi(url) {

      return pollApi(url).then(function({response, body}) {
        log("body is : ", body);
        return body;
      }).catch(function(e) {          
        let { response, body } = e;

        if (response.statusCode === 500) {
          if (!revisited[url]) { 
            log("Faced with error 500, retrying once", url);
            revisited[url] = true;
            runUrlOnThirdPartyApi(url); 
          } else {
            log("Faced with error 500 already once, so we do retry the url any more");
          }
        }

        if (response.statusCode === 429  ) {           
          return delay(THIRDPARTY_API_RETRY_INTERVAL_ON_429).then(() => {
            log("Faced with error 429 (all available slots on API within the authorized nb of concurrent calls) : retrying in 10 seconds ", url);
            runUrlOnThirdPartyApi(url);
          })

        }
      });
    }

   } catch (e) {
    log(
      "Error occured while trying to get infos on fn xxxxxxxxxx",
      e
    );
  }

 });

 export { handler };

Supporting_functions.js

export function delay(ms) {
  return new Promise(function(resolve) {
    setTimeout(resolve, ms);
  });
}
export function curl(url) {
  return new Promise(function(resolve, reject) {
    request(
      {
        method: "GET",
        url: url,
        headers: {             
          "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) xxxxxxxxxxxx"
        }
      },
      function(error, response, body) {
        if (error) {
          console.log("Error while placeing request");
          reject(error);
        } else if (response.statusCode < 200 || response.statusCode > 299) {
          console.log("[CURL] Rejected because non 200: ", response.statusCode, 'body: ', body);
          reject({ response, body });
        } else {
          console.log("resolved");
          resolve({ response, body });
        }
      }
    ).on("error", function(error) {
      console.log("Error during connection <<<<<<<<<<<<<<<", error);
    });
  });
}

export function ErrorHandlingHOF(handler) {
  return function(...fnArgs) {
    try {
      return handler(...fnArgs);
    } catch (error) {
      console.log('Exception occurred in the lambda handler', error);      
    }
  };
}
...