I am using the oracledb driver for my app combined with this library https://github.com/sagiegurari/simple-oracledb
I wish to send the results from my query in bulks, but I keep getting the error:
Error: Can't set headers after they are sent.
Here is my code:
router.get('/', function (req,res) {
"use strict";
oracledb.getConnection(connAttrs.database, function (err, connection) {
if (err) {
// Error connecting to DB
res.set('Content-Type', 'application/json');
res.status(500).send(JSON.stringify({
status: 500,
message: "Error connecting to DB",
detailed_message: err.message
}));
return;
}
connection.query("Select * from solvedtasks",{},{
splitResults: true, //True to enable to split the results into bulks, each bulk will invoke the provided callback (last callback invocation will have empty results)
bulkRowsAmount: 1000 //The amount of rows to fetch (for splitting results, that is the max rows that the callback will get for each callback invocation)
},
function onResults (err, results) {
if (err) {
res.set('Content-Type', 'application/json');
res.status(500).send(JSON.stringify({
status: 500,
message: "Error getting the user profile",
detailed_message: err.message
}));
} else if(results.length)
{
res.send(results);
}
else {
// Release the connection
console.log("done");
connection.release(
function (err) {
if (err) {
console.error(err.message);
} else {
console.log("GET /SolvedTasks : Connection released");
}
});
}
});
});
});
This error obviously happens because it keeps doing res.send(results) more than once. I get just the first 1000 rows and after that the error occurs. Any idea how to solve this, keep sending the results in bulks but not getting the error?
Related
Hello StackOverFlow Army,
im getting
Cannot set headers after they are sent to the client
Error in this code.
getUserInfo: async (req, res) => {
try {
const { id } = req.user;
// Check is User Data present in Redis
redis_client.GET("USER_" + id, (err, user) => {
if (err) {
console.log(err.message);
return res.status(500).json({ msg: "Server Error!" });
}
// If present Return User data
// Return User data
user = JSON.parse(user);
if (user) return res.json({ user });
});
// Else Fetch Data from Database
const user = await Users.findById(id).select("-password");
// Set to Redis
redis_client.SET(
"USER_" + id.toString(),
JSON.stringify(user),
"EX",
10,
(err, reply) => {
if (err) {
console.log(err.message);
return res.status(500).json({ msg: "Server Error!" });
}
}
);
// Return User data
res.json({ user });
} catch (error) {
return res.status(500).json({ msg: error.message }); // Line 77
}
},
Error On Line 77.
Please Help me, i cannot see why it is happening. Im sending response and there is no collision between sending response. Is it a good practice to store a user data in redis for faster fetching.
The Expiry time is very low like 10s so if user spam refresh it will help to fetch faster. Any suggestions is appreciated.
You need to put your else part inside the callback function of redis_client.GET , just below this line
**if (user) return res.json({ user });
what happens now is, if this above if condition goes true , then also the the code will move to the next line as return statement will just return from the callback function and not end the response cycle.
var express = require('express');
var pg = require('pg');
var app = express();
var connectionString = "postgres://...";
app.get('/', function (req, res, next) {
pg.connect(connectionString, function (err, client, done) {
if (err) {
console.log("not able to get connection " + err);
res.status(400).send(err);
}
client.query('SELECT * FROM employee WHERE empid=$1', [1], function (err, result) {
done(); // closing the connection;
if (err) {
console.log(err);
res.status(400).send(err);
}
res.status(200).send(result.rows);
});
});
});
app.listen(3000, function () {
console.log('Server is running.. on Port 3000');
});
This is my nodejs file and the connectionString is database information that connected heroku and postgreSQL.
But when I run this one, I only get
client.query('SELECT * FROM employee WHERE empid=$1', [1], function (err, result) {
^
TypeError: Cannot read property 'query' of null
How can I solve it?
In your error handler here:
if (err) {
console.log("not able to get connection " + err);
res.status(400).send(err);
}
client.query(...)
You need to add a return so that after you send the error status, the code does not continue to try to execute client.query() because client does not have a valid value in it if there was an error. So, change to this:
if (err) {
console.log("not able to get connection " + err);
res.status(400).send(err);
return;
}
client.query(...)
Though it has less of a consequence, the same is true here:
if (err) {
console.log(err);
res.status(400).send(err);
}
res.status(200).send(result.rows);
Where you need to add a return:
if (err) {
console.log(err);
res.status(400).send(err);
return;
}
res.status(200).send(result.rows);
The overall issue in these two cases is that while res.status(...).send(...) sends the response back to the client, it does not stop your code from continuing to execute after that so you still need proper flow control with if/else or an appropriate return to control the flow of execution of the code so after an error it doesn't immediately go execute other parts of the code that you don't want it to.
I am getting this error only when I call get method (Not every time).
Here is my node function which returns me a response.
exports.GetDepartmentList = function (req, res) {
fs.readFile('./api/tempFiles/department.json', 'utf8', function (err,response) {
res.status(200).send({
success: true,
data: JSON.parse(response)
});
return res.json();
dbConn.close();
}).catch(function (err) {
res.status(500).send({
success: false,
message: err.message
});
return res.json();
dbConn.close();
});
};
I already checked all the StackOverflow's questions but none of them are helpful for solving my problem.
This error occured when you send multiple responses to your client side.
I think you should try with something like this (without catch)
exports.GetDepartmentList = function (req, res) {
fs.readFile('./api/tempFiles/department.json', 'utf8', function (err, response) {
if (err) {
res.status(500).json({
success: false,
message: err.message
});
}
else {
res.status(200).json({
success: true,
data: JSON.parse(response)
});
}
dbConn.close(); // Really usefull ?
});
};
Hope it helps.
I am trying to write tests to ensure that my Express API is correctly returning the right HTTP status codes for various scenarios. I am using Mocha, and Supertest for requests to the API in the tests. Right now I'm getting very unexpected results, which are detailed below.
Using: Express, body-parser, Sequelize, Mocha, Supertest
GET /users/:id
models.User.find(req.params.id).complete(function(err, foundUser) {
if (err) {
logger.error(err, 'Error');
return err;
}
console.log('user: ' + foundUser);
if (foundUser != null) {
res.json({ user: foundUser.getJsonRepresentation() });
}
else {
res.status(404);
res.json({ error: 'Not found' });
}
});
Tests for this method
it('responds with the right user', function(done){
request(app)
.get(apiPath + '/users/' + createdUser.id)
.set('Accept', 'application/json')
.expect(function(res) {
res.body.user.id.should.equal(createdUser.id);
})
.expect(200, done);
});
it('responds with the right error code for non-existent resource', function(done) {
request(app)
.get(apiPath + '/users/1000')
.expect(404, function(err, res) {
console.log(err);
console.log('Response: ' + res);
done();
});
});
For the 404 test, I get this error: { [Error: Parse Error] bytesParsed: 12, code: 'HPE_INVALID_STATUS' } in the callback. The res is undefined.
I have tried several different syntax forms for this expect call: .expect(404, function(err, res) { and none of them have worked. I've also tried all the different syntax forms for this as well:
res.status(404);
res.json({ error: 'Not found' });
Can anyone offer some insight into what is going on here?
Maybe the issue is in the following code snippet:
if (err) {
logger.error(err, 'Error');
return err;
}
It seems to be triggering the error but not actually returning it to the supertest client.
You can try to return the error to the client instead of only logging it, like this:
if (err) {
logger.error(err, 'Error');
res
.status(500);
.json({ error: error.message });
return err;
}
I'm building a ExpressJS application with NodeJS. My question is there any performance difference if I do
app.get('/test', function(req, res) {
fn(function(err, data) {
if (err) {
return res.json(400, {
error: 1,
msg: "some error"
});
}
///more code
});
});
instead of
app.get('/test', function(req, res) {
fn(function(err, data) {
if (err) {
res.json(400, {
error: 1,
msg: "some error"
});
return;
}
///more code
});
});
Do returning the res variable make any addition load on the server. Both codes work, just the first looks better to me and I save 1 line.
On the contrary, I think many would tell you this sort of idiom is a very sound practice as it makes clear to the reader (often your future self) that you are exiting). What is very nice about the strategy in this particular case is that you can save a bit more code since you now only have a single statement in your conditional branch, which means you can lose some curly braces.
app.get('/test', function(req, res) {
fn(function(err, data) {
if (err) return res.json(400, {
error: 1,
msg: "some error"
});
///more code
});
});
But you asked if there was a performance difference. If there is, I think it would be all but imperceptible.
Returning an object in a function don't make additional load.
On your exemple, based on callback function, there is no difference.
But what if app.get return a Promise ?
This code will provide an Unhandled rejection Error
app.get('/test')
.then( (data) =>
{ /* do something with your data that can throw a functional error
for exemple request for a user on your database based on your data */
if (!user) res.json(401, {msg: 'USER NOT FOUND'});
if (user.someProperty) //will throw an error when user is not found
res.json(200, {msg: 'USER DID IT'});
})
.catch( (err) => {
res.json(500, {msg: 'OUTCH'});
throw(err);
});
This code will not
app.get('/test')
.then( (data) =>
{ /* do something with your data that can throw a functional error
for exemple request for a user on your database based on your data */
if (!user) return res.json(401, {msg: 'USER NOT FOUND'});
if (user.someProperty) //will not be evaluate when user is not found
return res.json(200, {msg: 'USER DID IT'});
})
.catch( (err) => {
res.json(500, {msg: 'OUTCH'});
throw(err);
});
When using promise always return ;)