Upon clicking a button on the frontend, I would like to execute a python script which takes between 10 - 30 seconds to run.
I am trying to call the python script in my post route/controller but am getting the following error:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
I would not like to send anything to the client until after the script has run.
Route/Controller:
const express = require("express");
const router = express.Router();
router.post("/solve", async function (req, res) {
const board = JSON.stringify({
board: req.body.grid,
});
const spawn = require("child_process").spawn;
const pythonProcess = spawn("python", ["./crossword/crossword.py", board]);
pythonProcess.stdout.on("data", (data) => {
// Do something with the data returned from python script
solved_data = JSON.parse(data.toString());
res.send(JSON.stringify(solved_data));
});
});
CodePudding user response:
The error is shown because you are sending data in the data
event which keeps on firing on every output change by python script which repeatedly sends the response to client (which is not good), to solve the issue you should send response only once and for that you should subscribe to the exit event of the process so that collect all output and then send the output as response when process is closed
const express = require("express");
const router = express.Router();
let data = '';
router.post("/solve", async function (req, res) {
const board = JSON.stringify({
board: req.body.grid,
});
const spawn = require("child_process").spawn;
const pythonProcess = spawn("python", ["./crossword/crossword.py", board]);
pythonProcess.stdout.on("data", (response) => {
// Keep collecting the data from python script
data = response;
});
pythonProcess.on('exit', function(code, signal) {
console.log('Python process is now completed send data as response');
let solved_data = JSON.parse(data);
res.send(JSON.stringify(solved_data));
//you can also check code to verify if exit was due to error or normal
});
});