Learning NodeJS/ExpressJS here. Below is an example of my extremely simple ExpressJS GET request that is supposed to return a JSON file.
app.get("/getFile", async (req, res) => {
if (res.headersSent) return;
try {
res.sendFile(
path.join(__dirname, "latest-data", "my-file.json"),
(err) => {
if (err) {
res.status(500).send("Internal Server Error");
}
}
);
} catch (error) {
console.error(error.stack);
}
});
While 99.9% of the time the request works as intended. However when stress testing with Apache JMeter to test 1000 concurrent users performing the request, I noticed that when I abort the request, the following error appears and my server process ends.
node:_http_outgoing:603
throw new ERR_HTTP_HEADERS_SENT('set');
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at new NodeError (node:internal/errors:387:5)
at ServerResponse.setHeader (node:_http_outgoing:603:11)
at ServerResponse.header (C:UsersUSERDesktopmy-projectmy-project-servernode_modulesexpresslibresponse.js:794:10)
at ServerResponse.send (C:UsersUSERDesktopmy-projectmy-project-servernode_modulesexpresslibresponse.js:174:12)
at C:UsersUSERDesktopmy-projectmy-project-serverindex.js:113:27
at C:UsersUSERDesktopmy-projectmy-project-servernode_modulesexpresslibresponse.js:450:22
at onaborted (C:UsersUSERDesktopmy-projectmy-project-servernode_modulesexpresslibresponse.js:1054:5)
at onfinish (C:UsersUSERDesktopmy-projectmy-project-servernode_modulesexpresslibresponse.js:1088:50)
at AsyncResource.runInAsyncScope (node:async_hooks:203:9)
at listener (C:UsersUSERDesktopmy-projectmy-project-servernode_moduleson-finishedindex.js:170:15) {
code: 'ERR_HTTP_HEADERS_SENT'
}
Now I can tell that it’s something to do with the server trying to send a response more than once, however I cannot seem to understand or figure a way how to avoid or use a try catch statement to avoid my server from crashing. This is an issue that will happen when the server traffic gets heavy, I would like to be able to bypass this.
By applying the following logic at the start if (res.headersSent) return; I would assume that it would work but it did not.