What to log to debug Error [ERR_HTTP_HEADERS_SENT]? - node.js

In an Express controller function, I am running into to this error Error [ERR_HTTP_HEADERS_SENT]. This occurs when I call res.json() if headers have already been set on the res object. However, I don't see place in my function (or middleware) where headers could be set prior to my calling res.json().
To debug the cause of this error, I thought I could add some logging. Prior to calling res.json, I could check if headers had been set and, if so, log some information about who set them.
async function get(req, res) {
...
if (res._header) {
logger.debug(...);
}
res.json(...);
Unfortunately, I don't see anything useful in the res object to log, any message that would indicate why/how the headers were set (or who set them). Any suggestions for what I could log to debug this issue? Or other debugging suggestions?

You can patch res.header res.send res.set to log the stack trace for you. For example this is my main application.
const express = require('express');
const app = express();
const someGoody = require('./stupid-blackbox');
/** patch the res **/
app.use((req, res, next) => {
const _header = res.header.bind(res); // .header and .set is an alias pair
const _send = res.send.bind(res);
res.header = res.set = (field, val) => {
console.trace('.header/.set called', field, val);
console.log('-----');
return _header(field, val);
}
res.send = (body) => {
console.trace('.send called', body);
console.log('-----');
return _send(body);
}
next();
})
// some innocent looking middleware
app.use(someGoody);
// my main routes
app.get('*', (req, res) => {
res.json({url: req.url});
})
app.listen(3000);
And for stupid-blackbox.js:
const express = require('express');
const router = express.Router();
router.use((req, res, next) => {
res.header('X-Crash-You', '1').send(':)');
next();
})
module.exports = router;
When ran, you will get this in the log:
Trace: .header/.set called X-Crash-You 1
at ServerResponse.res.header.res.set (C:\Users\eric_\Desktop\initial\play\index.js:11:13)
at router.use (C:\Users\eric_\Desktop\initial\play\stupid-blackbox.js:6:9)
at Layer.handle [as handle_request] (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:317:13)
at C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:275:10)
at Function.handle (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:174:3)
at router (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:47:12)
at Layer.handle [as handle_request] (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\layer.js:95:5)
-----
Trace: .send called :)
at ServerResponse.res.send (C:\Users\eric_\Desktop\initial\play\index.js:17:13)
at router.use (C:\Users\eric_\Desktop\initial\play\stupid-blackbox.js:6:36)
at Layer.handle [as handle_request] (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:317:13)
at C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:275:10)
at Function.handle (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:174:3)
at router (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:47:12)
at Layer.handle [as handle_request] (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\layer.js:95:5)
On the second line of each stack trace you can see the stupid-blackbox.js.
On a side note, res.json will not result in error if only res.header or res.set is called, the error is headers has been sent so that means somewhere in the code, res.send is called causing headers to be sent before your actual code.

Related

Object.fromEntries is not a function (Node.js error with Express)

I am developing a Node.js app, and it's working great on the local server. However on my Cpanel server (running Node 14.20.1) I am getting this strange error:
"Object.fromEntries is not a function"
The stack trace is
at app.post (/home/joshgncd/riverbank.app/auth/index.js:435:5) \\ this is just the line that prints the error
at Layer.handle [as handle_request] (/home/joshgncd/nodevenv/riverbank.app/auth/14/lib/node_modules/express/lib/router/layer.js:95:5)
at next (/home/joshgncd/nodevenv/riverbank.app/auth/14/lib/node_modules/express/lib/router/route.js:144:13)
at Route.dispatch (/home/joshgncd/nodevenv/riverbank.app/auth/14/lib/node_modules/express/lib/router/route.js:114:3)
at Layer.handle [as handle_request] (/home/joshgncd/nodevenv/riverbank.app/auth/14/lib/node_modules/express/lib/router/layer.js:95:5)
at /home/joshgncd/nodevenv/riverbank.app/auth/14/lib/node_modules/express/lib/router/index.js:284:15
at Function.process_params (/home/joshgncd/nodevenv/riverbank.app/auth/14/lib/node_modules/express/lib/router/index.js:346:12)
at next (/home/joshgncd/nodevenv/riverbank.app/auth/14/lib/node_modules/express/lib/router/index.js:280:10)
at cors (/home/joshgncd/nodevenv/riverbank.app/auth/14/lib/node_modules/cors/lib/index.js:188:7)
The function calling it never calls Object.fromEntries:
app.post('/auth/notion/action', async (req, res) => {
try {
const data = req.body
const tokens = users[req.query.email].notion_tokens
const notion = new Notion({
auth: tokens.access_token
})
let response = await notion.search(data)
res.send(response)
} catch (err) {
console.trace(err.message)
res.status(400).send(err.message)
}
})
Can someone help figure out why this is happening?
I also am sure it's not a Notion API error as I replaced let response = await notion.search(data) with an Axios HTTP request and still got this Object.fromEntries error.
I have fixed the issue by using this libary: polyfill-object.fromentries

req.headers.cookie is undefined

Whenever I run my program, this happens:
TypeError: Cannot read property 'toString' of undefined
at /home/runner/Factions-Online-Multiplayer-Clicker-Game/index.js:28:49
at Layer.handle [as handle_request] (/home/runner/Factions-Online-Multiplayer-Clicker-Game/node_modules/express/lib/router/layer.js:95:5)
at next (/home/runner/Factions-Online-Multiplayer-Clicker-Game/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/home/runner/Factions-Online-Multiplayer-Clicker-Game/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/runner/Factions-Online-Multiplayer-Clicker-Game/node_modules/express/lib/router/layer.js:95:5)
at /home/runner/Factions-Online-Multiplayer-Clicker-Game/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/home/runner/Factions-Online-Multiplayer-Clicker-Game/node_modules/express/lib/router/index.js:335:12)
at next (/home/runner/Factions-Online-Multiplayer-Clicker-Game/node_modules/express/lib/router/index.js:275:10)
at expressInit (/home/runner/Factions-Online-Multiplayer-Clicker-Game/node_modules/express/lib/middleware/init.js:40:5)
at Layer.handle [as handle_request] (/home/runner/Factions-Online-Multiplayer-Clicker-Game/node_modules/express/lib/router/layer.js:95:5)
I've done this before, but I'm not sure why it returns this. The code where the error happens is below.
app.get("/", (req, res) => {
var cookies = cookie.parse(req.headers.cookie.toString());
var accounts = loadjson('passwords.json');
if (cookies.username && cookies.password) {
if (cookies.username in accounts) {
if (accounts[cookies.username] === sha256(cookies.password)) {
res.render("html/game")
} else {
res.render("html/index");
}
} else {
res.render("html/index");
}
} else {
res.render("html/index");
}
});
The full program is here.
When you use cookie-parser package as a middleware it returns cookie in req.cookies object rather than req.headers.cookie.
app.get("/", (req, res) => {
var cookies = cookie.parse(req.cookies.toString());
//... Rest of the code
}
Read more about it here

Cannot read property 'program' of undefined in cookies?

I am beginner in Nodejs program I tried to do simple cookies program.I successfully set and delete the cookies successfully.but I could not get the cookies what I set before.It shows an error.can anyone tell me how to get the cookie in nodejs Thanks in advance....
const express=require("express");
const cookieParser=require("cookie-parser");
const app=express();
const router=express.Router();
const port=process.env.Port||8086;
app.use(router);
app.use(cookieParser());
router.get("/setcookie",function(req,res)
{
console.log("Come in to set the cookie");
res.cookie("program","NodeJS"/*,{maxAge:60000}*/);
res.cookie("Database","MongoDB"/*,{maxAge:1200000}*/);
console.log("Cookie set successfully");
res.send("Cookie set successfully");
});
router.get("/deletecookie",function(req,res)
{
console.log("come in to delete the cookie");
res.clearCookie("program");
res.send("Cookie deleted successsfully");
});
router.get("/getcookie",function(req,res)
{
console.log("Come in to read the cookie");
console.log(req.cookies['program']);
console.log(req.cookies['Database']);
res.send("Cookie Accessed successfully");
});
app.listen(port,function()
{
console.log("server is listening on port 8086");
});
ERROR I GOT:
TypeError: Cannot read property 'program' of undefined
at C:\Users\VIGNESH\WebstormProjects\cookies-middleware\simple-cookies.js:25:28
at Layer.handle [as handle_request] (C:\Users\VIGNESH\WebstormProjects\cookies-middleware\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\VIGNESH\WebstormProjects\cookies-middleware\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\VIGNESH\WebstormProjects\cookies-middleware\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\VIGNESH\WebstormProjects\cookies-middleware\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\VIGNESH\WebstormProjects\cookies-middleware\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\Users\VIGNESH\WebstormProjects\cookies-middleware\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\VIGNESH\WebstormProjects\cookies-middleware\node_modules\express\lib\router\index.js:275:10)
at Function.handle (C:\Users\VIGNESH\WebstormProjects\cookies-middleware\node_modules\express\lib\router\index.js:174:3)
at router (C:\Users\VIGNESH\WebstormProjects\cookies-middleware\node_modules\express\lib\router\index.js:47:12)
You need to add the cookieParser() before the router, so the code will be
app.use(cookieParser());
app.use(router);
Because otherwise the control is not even getting into cookieParser

Expressjs Routes based on an Array of objects

Trying to setup routes based on an array of objects in ExpressJS, but I'm getting an error when attempting to access the route.
The error is this:
TypeError: shares[Symbol.iterator] is not a function
at router
(C:\Users\rutherfordc.AA\Documents\GitHub\transientComplete\transient-server\routes\shares.js:10:18)
at Layer.handle [as handle_request] (C:\Users\rutherfordc.AA\Documents\GitHub\transientComplete\transient-server\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\rutherfordc.AA\Documents\GitHub\transientComplete\transient-server\node_modules\express\lib\router\index.js:317:13)
at C:\Users\rutherfordc.AA\Documents\GitHub\transientComplete\transient-server\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\rutherfordc.AA\Documents\GitHub\transientComplete\transient-server\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\rutherfordc.AA\Documents\GitHub\transientComplete\transient-server\node_modules\express\lib\router\index.js:275:10)
at expressInit (C:\Users\rutherfordc.AA\Documents\GitHub\transientComplete\transient-server\node_modules\express\lib\middleware\init.js:40:5)
at Layer.handle [as handle_request] (C:\Users\rutherfordc.AA\Documents\GitHub\transientComplete\transient-server\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\rutherfordc.AA\Documents\GitHub\transientComplete\transient-server\node_modules\express\lib\router\index.js:317:13)
at C:\Users\rutherfordc.AA\Documents\GitHub\transientComplete\transient-server\node_modules\express\lib\router\index.js:284:7
from code like this:
var router = (shares) => {
for(let share of shares){
shareRouter.route(`/${share.name}`)
.get((req, res) => {
var fileList = [];
fs.readdir(share.location, (err, files) => {
for(let file in files){
fileList.push(file);
shareRouter.route(`/${file}`)
.get((req, res) => {
var filePath = path.join(share.location, file);
res.download(filePath, `${file}`);
});
}
}).then(()=>{
res.render('shareFiles', fileList);
});
});
}
};
shares is defined prior to the router function call. What's supposed to happen is that when the application starts, it looks in the config file, imported earlier, get's the list of folders to share and sets them up based on the name property of the object, then goes through each of the files in the folder to create routes based on their file names, which is then passed into a pug template that provides links to the file routes.

node.js TypeError: undefined is not a function on app.get("/")

I'm trying out node.js and some hello world examples and I'm getting this error
TypeError: undefined is not a function
at c:\users\admin\documents\visual studio 2015\Projects\TheBoard\TheBoard\server.js:10:13
at Layer.handle [as handle_request] (c:\users\admin\documents\visual studio 2015\Projects\TheBoard\TheBoard\node_modules\express\lib\router\layer.js:95:5)
at next (c:\users\admin\documents\visual studio 2015\Projects\TheBoard\TheBoard\node_modules\express\lib\router\route.js:131:13)
at Route.dispatch (c:\users\admin\documents\visual studio 2015\Projects\TheBoard\TheBoard\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (c:\users\admin\documents\visual studio 2015\Projects\TheBoard\TheBoard\node_modules\express\lib\router\layer.js:95:5)
at c:\users\admin\documents\visual studio 2015\Projects\TheBoard\TheBoard\node_modules\express\lib\router\index.js:277:22
at Function.process_params (c:\users\admin\documents\visual studio 2015\Projects\TheBoard\TheBoard\node_modules\express\lib\router\index.js:330:12)
at next (c:\users\admin\documents\visual studio 2015\Projects\TheBoard\TheBoard\node_modules\express\lib\router\index.js:271:10)
at expressInit (c:\users\admin\documents\visual studio 2015\Projects\TheBoard\TheBoard\node_modules\express\lib\middleware\init.js:33:5)
at Layer.handle [as handle_request] (c:\users\admin\documents\visual studio 2015\Projects\TheBoard\TheBoard\node_modules\express\lib\router\layer.js:95:5)
Here's my code
var http = require("http");
var express = require("express");
var app = express();
app.get("/",
function(res, req) {
res.send("<html><body><h1>Express</h1></body></html>");
});
app.get("/api/users",
function(req, res) {
res.send({ name: "Louis", isValid: true, group: "Admin" });
});
var server = http.createServer(app);
server.listen(3000);
I'm only getting the error when I hit http://localhost:3000/
I do not get any error when I hit http://localhost/api/users
problem in a ordering of parameter.. req object doesn't have any send function.
var http = require("http");
var express = require("express");
var app = express();
app.get("/",
function(req, res) {
res.send("<html><body><h1>Express</h1></body></html>");
});
app.get("/api/users",
function(req, res) {
res.send({ name: "Louis", isValid: true, group: "Admin" });
});
var server = http.createServer(app);
server.listen(3000);
Your function for app.get("/") is not correct. The order in which you have passed the arguments is not right. The correct way is to first give request object and then the response object. The correct way is to write like this:
app.get("/",
function(req, res) {
res.send("<html><body><h1>Express</h1></body></html>");
});
Hope this might work for you. :)

Resources