0

I am trying to run a simple child process in my express js route and return a json message with the stdout as the message value. But for some reason the stdout value is undefined any pointers?

express route code

const express = require("express")
const asyncHandler = require("express-async-handler")
const cp = require('child_process')
const router =  express.Router()

router.get("/status", asyncHandler( async (req, res) => {
    
    let msg 

    cp.exec('ls', (err, stdout, stderr) => {
        console.log('#1, exec')
        console.log(stdout)
        msg = stdout
    })

    res.json({message:`${msg}`})
}))

module.exports = router
Jordan Rob
  • 322
  • 2
  • 16
  • `res.json` executes before the child process does. Try putting it inside `cp.exec`'s callback at the end. By the way, I wouldn't create a child process for every request; that seems quite inefficient. If you simply want to `ls` why not just use `fs.readDir`? – code Jun 30 '22 at 02:53

1 Answers1

1

You have to move the response INSIDE the callback. cp.exec() is asycnhronous so it starts up and then continues executing the next lines of code. The callback is called sometime later. So, you need to send your response INSIDE the callback.

const express = require("express")
const cp = require('child_process')
const router =  express.Router()

router.get("/status", (req, res) => {
    
    cp.exec('ls', (err, stdout, stderr) => {
        if (err) {
             console.log(err);
             res.sendStatus(500);
             return;
        }
        console.log('#1, exec');
        console.log(stdout);
        res.json({message:`${stdout}`});
    })
});


module.exports = router;

And, this route handler doesn't seem to have any reason to use asyncHandler as there's no async/await in use.

And, you should properly handle errors.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Incase I had async/await in use for example creating a new record of a model called Log for a mongodb collection `const newLog = await Log.create({})` how would I structure the function – Jordan Rob Jun 30 '22 at 22:09
  • @JordanRob - If you are awaiting a function that returns a promise, then you can just program serially since there are no asynchronous callbacks involved. – jfriend00 Jul 01 '22 at 04:10
  • I had placed the await operation in the previous comment in my child process callback function shown above and got a syntax error for the await keyword, it confused me since the child process function is within an async function – Jordan Rob Jul 01 '22 at 13:42
  • @JordanRob - Sorry, but I can't help with code I can't see. You can write a new question with the relevant code if you want further help with your issue using `await`. – jfriend00 Jul 01 '22 at 14:53
  • Alright let me do just that I'll plug the question [here](https://stackoverflow.com/questions/72837798/executing-a-child-process-within-an-async-await-function-under-an-express-js-rou) – Jordan Rob Jul 02 '22 at 09:04