Search code examples
node.jstypescriptexpressgoogle-cloud-run

Cloud Run does not response but the script is working


I'm running a pipeline using cloud run. The code work as in test and on cloud run (the data was then loaded to bigquery so I can confirm this). However, after the code is executed, cloud run does not return any response back and keep running till timeout (which raised an error to cloud tasks).

here is my code example

app.use("/", (req, res) => {
  Joi.object<RequestBody>({
    //some variables with Joi validation
  })
    .validateAsync(req.body)
    .then(async (variables ) => {
      return runPipeline(variables)
        .then((result) => {
          res.status(200).json({ result });
        })
        .catch((error) => {
          res.status(500).json({ error }); 
        });
    }).then(
      (result) => res.status(200).json({result})
    )
    .catch((error) => {
      res.status(500).json({ error });
    });
});

I tried to use res.status to send responses back after the code is done, however it does not work


Solution

  • Without being able to run the code myself, I can't say for sure, but I think the nested promises aren't returning the result to the following .then method. If you want to keep the nested promise, I think the result probably needs to be returned:

    // Option 1 (minor changes, but still a little hard to read.)
    app.use("/", (req, res) => {
      Joi.object<RequestBody>({
        //some variables with Joi validation
      })
        .validateAsync(req.body)
        .then(async (variables ) => {
          return runPipeline(variables)
            .then((result) => {
              return result;
            })
        }).then(
          (result) => res.status(200).json({result})
        )
        .catch((error) => {
          res.status(500).json({ error });
        });
    });
    

    Since you're using async already, I'm wondering if you're ok with a slight refactor? I think something like this might make it easier to read and debug:

    // Option 2 (more changes, but easier to read.)
    app.use("/", async (req, res) => {
      try {
        const variables = await Joi.object<RequestBody>({
          //some variables with Joi validation
        }).validateAsync(req.body);
        const result = runPipeline(variables);
        return res.status(200).json({ result });
      } catch (error) {
        return res.status(500).json({ error });
      }
    });