Search code examples
javascriptgoogle-cloud-platformjestjsgoogle-cloud-functionschild-process

Invalid json while trying gcloud functions commands via javascript


I am trying to run a sample test using Jest to verify if my Google Cloud Function is working fine or not but I am constantly getting following error.

I have tried running the following command directly in windows power shell but still the same error which can be escaped using \ before double quotes.

Error: Command failed: gcloud beta functions call cf-1 --region europe-west1 --data '{"data":"eyJkYXRhIjoiMSJ9"}'
ERROR: (gcloud.beta.functions.call) Invalid value for [--data]: Is not a valid JSON: No JSON object could be decoded

test file

const childProcess = require('child_process');

describe('Test CF', () => {
    it('print outs the error message when received JSON is blank', done => {
        const msg = { data: '1' };
        const encodedMsg = Buffer.from(JSON.stringify(msg)).toString('base64');
        const data = JSON.stringify({ data: encodedMsg });
        const executeResultOutput = childProcess.execSync(`gcloud beta functions call cf-1 --region europe-west1 --data '${data}'`).toString();

        const logs = childProcess
            .execSync(
                `gcloud functions logs read cf-1 --region europe-west1 --execution-id ${executionIdObj}`,
            )
            .toString();

        expect(logs).toEqual(expect.stringContaining('Error..'));
    });
});

Update#1: Still the same issue...

enter image description here


Solution

  • I have tried to replicate your situation and the issue you're experiencing by doing the following:

    First, I deployed a simple Cloud Function using Node.js 8:

    /**
     * Responds to any HTTP request.
     *
     * @param {!express:Request} req HTTP request context.
     * @param {!express:Response} res HTTP response context.
     */
    exports.simpleFunction = (req, res) => {
      let data = req.query.data || req.body.data || 'Didn\'t work!';
      res.status(200).send(data);
    };
    

    After that, I followed a Google Cloud Platform Quickstart guide to create a simple Node.js app, which I then modified to call my function locally. I have added some lines of the code, which you have in your example to call the function:

    'use strict';
     
    // [START gae_node_request_example]
    const express = require('express');
    const childProcess = require('child_process');
     
    const app = express();
    
    // The lines you used for a function call 
    const msg = { data: '1' };
    const encodedMsg = Buffer.from(JSON.stringify(msg)).toString('base64');
    const data = JSON.stringify({ data: encodedMsg });
    const executeResultOutput = childProcess.execSync(`gcloud beta functions call b-func --region us-central1 --data '${data}'`).toString();
     
     
    app.get('/', (req, res) => {
      res
        .status(200)
        .send(executeResultOutput)
        .end();
    });
     
    // Start the server
    const PORT = process.env.PORT || 8080;
    app.listen(PORT, () => {
      console.log(`App listening on port ${PORT}`);
      console.log('Press Ctrl+C to quit.');
    });
    // [END gae_node_request_example]
     
    module.exports = app;
    

    The code above worked for me and here is the output that I received:

    executionId: 6n6pf9720dsj result: eyJtZXNzYWdlIjoiMSJ9
    

    The only time I was able to get the same ERROR as yours: Is not a valid JSON: No JSON object could be decoded was when I passed the data value without surrounding it with quotes:

    const data = {"data":"some data"};
    const executeResultOutput = childProcess.execSync(`gcloud beta functions call b-func --region us-central1 --data '${data}'`).toString();
    

    Edit:

    I have tested the code that I mentioned above in Linux environment. Once I tried to run it in Windows I got the same error.

    Since the code is being run locally, PowerShell still will need to escape the parameters as John pointed out.

    As I see you've opened a new question regarding this issue already. Try the solution that was offered there - it worked for me.