1

I have a function which needs to be called when I hit the PUT API. Actually what I want to achieve is, a file gets created when the API is called.. lets say via Postman and that file needs to be stored inside a GCP bucket... for some reason it is not working as I expect it to be... I also don't get any errors. Below is my code snippet:

app.put('/api/ddr/:ticket_id', (req, res) => {
    const ticket_id = req.params.ticket_id;
    const requestBody = req.body;
    if(!requestBody || !ticket_id){
        res.status(404).send({message: 'There is an error'});
    }
    var fs = require('fs');
    var writer = fs.createWriteStream(filename,{ 'flags': 'a'
    , 'encoding': null
    , 'mode': 0666
    });
    writer.write(JSON.stringify(requestBody));
    res.status(201).send('all ok');
    uploadFile().catch(console.error);
  });

  async function uploadFile() {
    await storage.bucket(bucketName).upload(filePath);
    console.log("Trying to upload file to bucket");
    console.log(`${filePath} uploaded to ${bucketName}`);
  }


 

1 Answers1

0

The issues are you send your response before the file has been uploaded, and you're not handling the asynchronous code, try something like this.

async function uploadFile() {
  // TODO pass these variables as parameters and dont use
  // global variables
  console.log('Trying to upload file to bucket')
  await storage.bucket(bucketName).upload(filePath)
  console.log(`${filePath} uploaded to ${bucketName}`)
}

app.put('/api/ddr/:ticket_id', async (req, res) => {
  const ticket_id = req.params.ticket_id
  const requestBody = req.body
  if (!requestBody || !ticket_id) {
    res.status(404).send({ message: 'There is an error' })
  }
  var fs = require('fs')
  fs.writeFileSync(filename, requestBody)
  try {
    // You need to await this so that the promise can resolve
    // This is very important when using a cloud function
    // Your prior code didnt handle this
    await uploadFile()
  } catch (error) {
    console.error(`File upload failed with the following error: ${error}`)
  }
  // When everything is complete, then we send a response to the client
  return res.status(201).send('all ok')
})
omeanwell
  • 1,847
  • 1
  • 10
  • 16
  • I am getting below logs ... even though the file gets created... Server listening on the port::::::8080 Trying to upload file to bucket File upload failed with the following error: Error: ENOENT: no such file or directory, open './ddr_requests_2022_08_22_20:45.json' – AAYUSH MOHTA Aug 22 '22 at 15:29
  • Are you passing the right bucket name and file path / name? – omeanwell Aug 22 '22 at 15:36
  • I missed to mention await before uploadFile.... now I am getting below error in Postman: Error: socket hang up – AAYUSH MOHTA Aug 22 '22 at 15:55
  • Yes, I am passing right bucket name and filepath var filePath = './'+filename; and file name is the json file which gets created ddr_2022_08_23_2:11.json res is returned as all ok. But the below error still persists: file upload failed with the following error: Error: ENOENT: no such file or directory, stat './ddr_2022_08_23_2:11.json' – AAYUSH MOHTA Aug 22 '22 at 20:47
  • Response is returned before the file is created is what I am able to figure out. – AAYUSH MOHTA Aug 23 '22 at 13:19
  • I edited my response to create the file in a different way, try that. – omeanwell Aug 23 '22 at 14:17
  • i just called a timeout function like below before calling uploadFile and it worked: async function hangOn() { return new Promise((resolve) => setTimeout(resolve, 1000)); } Thanks for your help!! – AAYUSH MOHTA Aug 24 '22 at 07:41