В настоящее время я развертываю эту облачную функцию в своем приложении Firebase и буду использовать среду выполнения Node v8, поэтому я могу использовать синтаксис async / await .
У меня возникли проблемы с обработкой различных типов ошибок, которые могут возникать в одной и той же функции.
После завершения функция должна получить параметр url для отправки запроса.к этому url , почистите тело response для некоторых данных и сохраните его в базе данных.На данный момент, он просто возвращает ту же строку URL, которую он получил для целей тестирования.
Пока у меня есть следующее:
const functions = require('firebase-functions');
const request = require('request');
const cheerio = require('cheerio');
exports.getDataFromUrl = functions.https.onCall((data) => {
// PROMISIFIED REQUEST TO USE WITH ASYNC AWAIT
const promisifiedRequest = function(options) {
return new Promise((resolve,reject) => {
request(options, (error, response, body) => {
if (error) {
return reject(error);
}
return resolve(response);
});
});
};
// CHECK IF URL IS PRESENT, IF NOT, THROW ERROR
if (!data.url) {
throw new functions.https.HttpsError('invalid-argument','The URL parameter was invalid.');
}
// URL passed from the client.
const url = data.url;
// IIFE ASYNC FUNCTION
(async function() {
// TRY BLOCK
try {
// REQUEST OPTIONS TO THE URL
const urlOptions = {
url: 'https://www.someINEXISTENT.url',
method: 'GET',
gzip: true,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.96 Safari/537.36'
},
jar: true
};
// CREATE RESPONSE AND CHEERIO OBJECT
let response = null;
let $ = null;
// SEND REQUEST TO URL, AND PARSE WITH CHEERIO
response = await promisifiedRequest(urlOptions);
$ = cheerio.load(response.body);
} // TRY BLOCK - END
// CATCH BLOCK
catch (error) {
console.log('Caught an error: ' + error);
throw new functions.https.HttpsError('unknown', error.message, error);
}
console.log('End of async function...');
})()
return {
yourUrl : url
};
});
Мой первый случай ошибки, который происходиткогда URL недействителен, работает просто отлично.Выполнение останавливается, когда я выкидываю следующую ошибку:
throw new functions.https.HttpsError('invalid-argument','URL invalid.');
Насколько я понял, нужно выкинуть это HttpsError
, чтобы можно было поймать клиента,И это работает.Я получаю эту ошибку на клиенте, когда это происходит.
Моя проблема связана со вторым типом ошибки, которая должна быть обнаружена оператор try / catch внутри моей асинхронной функции .Эта ошибка должна возникать, когда я пытаюсь запросить несуществующий URL, например.
Что происходит, вот что (рисунок ниже):
Блок catch активирован, и я вижу `console.log () на моей консоли функций, но почему-то не выдает ошибку, и он жалуется на то, что «выбрасывает внутри асинхронную функцию без блока catch», хотя я выкидываю его из блока catch.Мой клиентский код не получает эту ошибку вообще.С точки зрения моего клиента, функция завершается без каких-либо ошибок.
Ошибка:
Ошибка: (узел: 5160) UnhandledPromiseRejectionWarning: необработанное отклонение обещания.Эта ошибка возникла либо в результате выброса асинхронной функции без блока catch, либо в результате отклонения обещания, которое не было обработано с помощью .catch ().(код отклонения: 1)
Я попытался добавить и внешние try/catch
блоки.А также использование .catch()
после асинхронного IIFE для выброса ошибки за пределы асинхронной функции, но это не решило проблему.
Что я делаю не так?