Benjamin RD
Benjamin RD

Reputation: 12034

Create an upload file to google cloud storage

I'm trying to generate and upload a file to google cloud storage. Generating the document locally and uploading it to the storage everything works properly. But once the service is deployed I get the error:

{
  "code": 500,
  "reason": "Unknow exception",
  "message": "Error: write EPIPE",
  "referenceError": "https://docs.nestjs.com/exception-filters",
  "exceptionText": {
    "errno": "EPIPE",
    "code": "EPIPE",
    "syscall": "write"
  }
}

My current method to create the document is:

const storage =
      ENDPOINTS.GOOGLE_STORAGE_BUCKET_KEY != ''
        ? new Storage({
            keyFilename: 'myfile.json',
          })
        : new Storage();

const content = '<h1>Hello world!</h1>';

    const myBucket = storage.bucket(ENDPOINTS.STORAGE_BUCKET);
    const file = myBucket.file(filename);
    file.metadata = { contentType: 'application/pdf' };

    await pdf.create(content).toBuffer(async (err, buffer) => {
      //destination: `D2C_D2D_ACTIVITY_SVC/drop_permission/${filename}`,
      console.log(buffer);
      await myBucket
        .file(`path/${filename}`)
        .save(buffer, {
          public: true,
          gzip: true,
          resumable: false,
          validation: false,
          metadata: {
            cacheControl: 'no-cache',
          },
        });

    });

Not sure why is not working once the service is deployed and I didn't find any right clue to solve it. Can someone help me?

Upvotes: 1

Views: 3067

Answers (2)

V.Tur
V.Tur

Reputation: 1417

I prefer use MulterGoogleStorage for work with google-storage:

import { Body, Controller, Post, UploadedFiles, UseInterceptors } from '@nestjs/common';
import { FilesInterceptor } from '@nestjs/platform-express';

import * as path from 'path';
import  MulterGoogleStorage  from 'multer-google-storage';

@Controller()
export class AppController {
  constructor() {}

  @Post()
  @UseInterceptors(FilesInterceptor('file', null, {
    storage: new MulterGoogleStorage({
      projectId: 'your project id',
      keyFilename: path.join(__dirname, '../myfile.json'),
      bucket: ENDPOINTS.STORAGE_BUCKET,
      filename: (req, file, cb) => {
        const fileNameSplit = file.originalname.split('.');
        const fileExt = fileNameSplit.pop();
        cb(null, `${Date.now()}.${fileExt}`);
      }
    })
  }))
  async save(@UploadedFiles() file, @Body() body: any): Promise<any> {
    console.log(file);
    return;
  }
}

Need to install "@types/multer" and "multer-google-storage"

Upvotes: 3

Rafael Lemos
Rafael Lemos

Reputation: 5819

Since you cannot create the file locally you can also use a Stream to upload it. Try using the code below:

const myBucket = storage.bucket(ENDPOINTS.STORAGE_BUCKET);
let pdfStream = pdf.create(content).toStream();
let remoteWriteStream = bucket.file(`path/${filename}`).createWriteStream({ 
    metadata : { 
        contentType : 'application/json' 
    }
});
pdfStream.pipe(remoteWriteStream)
    .on('error', err => {
        return callback(err);      
    })
    .on('finish', () => {
        return callback();
});

Let me know if this works.

Upvotes: 1

Related Questions