Я не понимаю ошибку, которую я получаю, и не могу выполнить некоторые "обещанные" действия в 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);
}
};
}