【发布时间】:2019-03-12 17:17:58
【问题描述】:
我目前正在将此云功能部署到我的 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 以便能够抓住客户。它有效。当它发生时,我在客户端收到此错误。
我的问题在于第二种类型的错误,它应该被我的 async 函数 中的 try/catch 语句捕获。例如,当我尝试请求不存在的 url 时,应该会发生该错误。
发生的事情是这样的(下图):
catch 块被激活,我可以在我的函数控制台上看到 `console.log(),但不知何故它不会抛出错误,并且它抱怨“在没有 catch 块的情况下抛出异步函数”,即使我是从一个 catch 块内扔它的。我的客户端代码根本没有收到此错误。从我的客户的角度来看,函数完成时没有任何错误。
错误:
错误:(节点:5160)UnhandledPromiseRejectionWarning:未处理的承诺 拒绝。此错误源于在异步内部抛出 没有 catch 块的函数,或者拒绝一个没有 用 .catch() 处理。 (拒绝编号:1)
我已经尝试添加和外部try/catch 块。并且还在 async IIFE 之后使用 .catch() 将错误抛出到 async 函数之外,但这并没有解决问题。
我做错了什么?
【问题讨论】:
-
如果您要显示错误消息的文本,请将其复制到问题本身中,而不是添加屏幕截图。屏幕截图难以阅读,无法在 SO 上搜索。
-
谢谢。我会编辑并添加它。
标签: javascript firebase async-await try-catch google-cloud-functions