【问题标题】:Trying to do fs.writefile() inside an async cloud function (node v8)尝试在异步云函数(节点 v8)中执行 fs.writefile()
【发布时间】:2019-08-05 06:05:56
【问题描述】:

我目前正在构建一个云功能来从电子商务网站上抓取一些数据。我在 Node.js v8 环境中运行它们,所以我可以使用 async/await 而无需转译。

我需要一种方法来保存带有来自网站的 html 响应的文件,以便我可以检查它并决定如何最好地抓取它。而且我无法让它发挥作用。

正如我在很多地方发现的那样,我需要一种方法来承诺 fs.writeFile() 函数,以便我可以 await 为它。我已经尝试使用util.promisify 并在下面构建自定义函数(两者都产生相同的结果,当我await 获得结果时,我的云函数崩溃了):

index.js(云函数的主文件 - 简化版)

const functions = require('firebase-functions');
const request = require('request');
const cheerio = require('cheerio');
const fs = require('fs');

// PROMISIFY WRITEFILE TO SAVE URL RESPONSE
const promisifiedWriteFile = function(text) {
  return new Promise((resolve, reject) => {
    fs.writeFile('./response.html', text, err => {
      if (err) {
        return reject(err);
      }
      return resolve();
    });
  });
};

exports.getUrlProductDetails = functions.https.onCall(
  async (data) => {

    try {
      // SEND REQUEST TO URL PRODUCT PAGE, PARSE WITH CHEERIO
      response = await promisifiedRequest(productURL);
      $ = cheerio.load(response.body);

      // TRYING TO SAVE FILE
      await promisifiedWriteFile('12345'); // <----- THIS IS CRASHING
    } // TRY BLOCK - OUTER - END

    catch (err) {
      console.log(err);
      throw new functions.https.HttpsError('unknown', 'Some internal error', err);
    }

  console.log('End of async function...');

  return {
    productDetails: productDetails,
    body: response.body // My client code is getting the body response just fine
  };

注意1:这是代码的简化版本,但导致函数崩溃的单行代码是:await promisifiedWriteFile('12345');,当我将其注释掉时,其他一切正常。 p>

注意 2: 文件 response.html 被创建(内容为空),即使此时函数崩溃。

注意3:我应该尝试写response.body'12345' 仅用于测试。但无论哪种方式都会崩溃。

我做错了什么?

编辑

// THIS IS WHAT LOGS OUT OF MY FUNCTION
info: User function triggered, starting execution
info: Execution took 2034 ms, finished with status: 'crash'

以下是我的客户端得到的:错误消息只是internal,因为云功能避免将内部错误详细信息传递给客户端。

注意4:我还没有部署这个功能。这都是关于本地开发的。

【问题讨论】:

  • 你能分享错误信息吗?
  • 分享你得到的错误并使用promisified fs方法而不是手动包装它nodejs.org/api/fs.html#fs_fs_promises_api或使用来自bluebird的Promisifly或使用npm fs-extra
  • fs_promises_api 在节点 8 中不可用
  • @Stanimirovv 刚刚添加了错误详情。
  • @AZ_ 刚刚添加了错误详情。

标签: javascript node.js firebase async-await google-cloud-functions


【解决方案1】:

我已经做到了。

根据this Firebase youtube videoos.tmpdir()只有一个目录可以被你的函数代码写入。

以下也是如此,现在它可以工作了:

index.js

const fs = require('fs');
const os = require('os');
const path = require('path');
const tmpdir = os.tmpdir();
const filePath = path.join(tmpdir,'response.html');

// PROMISIFY WRITEFILE TO SAVE URL RESPONSE
const promisifiedWriteFile = function(text) {
  return new Promise((resolve, reject) => {
    fs.writeFile(filePath, text, err => {
      if (err) {
        return reject(err);
      }
      return resolve();
    });
  });
};

从我正在调用的函数内部:

await promisifiedWriteFile(response.body);

在这个链接上也找到了一些相关的文档:

https://cloud.google.com/functions/docs/concepts/exec

【讨论】:

  • “os.tmpdir() 只有一个目录是可写的”。突出这一点!你拯救了我的理智!
【解决方案2】:

我相信您不允许在 Firebase 函数上写入文件系统。尝试写信给/tmp,见Does Cloud Functions for Firebase support file operation?

但我认为你不应该是writingresponse.html,而是应该在 Firebase 函数返回的响应中设置文本和状态码。

【讨论】:

  • 我会检查的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-07
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
相关资源
最近更新 更多