GCS 下载尝试导致 state.buffer[0].length 上“无法读取 null 属性”

问题描述 投票:0回答:1

我正在尝试将 Google Cloud Storage 对象下载到运行 Node.js 的 Google Cloud Run 服务中的

/tmp
。我遵循了本教程并有以下代码:

exports.resizeImage = async (eventData) => {
  const file = storage.bucket(eventData.bucket).file(eventData.name);

  // Resolve the image extension
  const [metadata] = await file.getMetadata();
  const extension = metadataContentTypeToExtension(metadata.contentType);

  const tempLocalPath = `/tmp/${path.parse(file.name).base}.${extension}`;

  console.log(tempLocalPath); // Prints "/tmp/clpeytui4003nfcsjqjyifk0d.jpg"

  try {
    // This is just for testing to see if I'm pointing at the object correctly
    const url = await file.getSignedUrl({
      action: 'read',
      expires: '03-17-2025',
    });
    console.log(`Here's an access URL: ${url}`);
  } catch (err) {
    console.error('Unable to get presigned URL:');
    console.error(err);
  }

  // Download file from bucket.
  try {
    console.log(`Downloading ${file.name} to ${tempLocalPath}...`);
    const dlPromise = file.download({ destination: tempLocalPath });
    dlPromise.catch((err) => {
      console.error('Download failed (caught in promise catch).');
      console.error(err);
    });
  } catch (err) {
    console.error(`File download failed: ${err}`);
    return;
  }

这是我在 Cloud Run 日志中得到的内容:

如果我将预签名 URL 复制并粘贴到浏览器中,它就可以工作,所以我很确定我正确定位了该文件。我还为该服务授予了

storage.admin
角色(因为它抱怨无法在某一时刻列出存储桶内容),所以我 认为 我已经授予了它所需的权限...

据我所知,服务/代码似乎无法获取数据流来下载文件,但我不确定这是否是问题所在。我尝试指定自己的下载函数,看看是否是 GCS 库错误:

const downloadFile = (file, downloadPath) =>
  new Promise((resolve, reject) => {
    console.log('Attempting to download file...');
    file
      .createReadStream()
      .pipe(fs.createWriteStream(downloadPath))
      .on('finish', () => {
        console.log(`Image downloaded locally to ${downloadPath}`);
        console.log(`File size: ${fs.statSync(downloadPath).size} bytes`);
        resolve();
      })
      .on('error', (err) => {
        console.error('Failed to download file.', err);
        reject(err);
      });
  });

但是我在同一个底层

stream-shift
调用中遇到了相同的错误,所以我猜这正是 Node 使用的。

奇怪的是我在任何地方都没有看到任何自定义错误消息......

关于可能出什么问题或者我下一步应该尝试什么有什么想法吗?

node.js google-cloud-storage
1个回答
0
投票

访问未定义值的 length 属性时,会发生“TypeError:无法读取未定义的属性(读取‘length’)”错误。要解决此错误,请确保仅访问支持它的数据类型(数组和字符串)的 length 属性。在访问 length 之前检查值的类型是否正确。

您还可以在访问 length 属性之前检查值的类型是否正确。

//Check if array before accessing length if (Array.isArray(value)) {   const result = value.length;   console.log(result); } else {   console.log('The value is NOT an array'); } 

// Check if string before accessing length if (typeof value === 'string') {   const result = value.length;   console.log(result); } else {   console.log('The value is NOT a string'); }

查看此有用的官方文档以了解流式下载

另请检查这些链接,其中讨论了类似的实现:

  1. GCS 文件流进入 fsreadstream

  2. Node.js 流读写

  3. 如何从GCS读取流文件

© www.soinside.com 2019 - 2024. All rights reserved.