When to client.end with promises syntax
See original GitHub issueI use node 8.11.1, express 4.16.3, pg 7.4.2.
So, I am using a Client to connect to the database, with certain privileges and signup new users. I am using promises syntax for my function. I don’t know when to client.end()
when everything goes well. In the docs I dont see a client.end()
with the promise syntax. So, here is my function
const signup = (user) => {
return new Promise((resolved, rejeted)=>{
getUser(user.email)
.then(res => {
if (!res) {//email taken
client.end();
return resolved(false);
}
return res; //true if email not taken
})
.then(res=>{
return crypto.hashPassword(user.password); //return hashed password
})
.then(res=>{
if (res) { //we have a hashed password
client.query('insert into user(mail, password) values ($1,$2)',[user.email, res])
.then(res=>{
client.end(); //<Remove this
return resolved(true);
})
} else { //crypto.hashPassword returned false, so there is an error
client.end();
return rejeted('error while signup');
}
})
.catch(error => {
rejeted('error while signup');
client.end();
});// catch
}) //promise
};//signup
The first time I use the signup form, it works perfectly.
If I try to use it again (use the menu to get to the form, not hit back in the browser), then the form just hangs and I get no errors. If I remove the client.end()
marked with <Remove this
, it works perfectly.
I would really like your opinion on what am I missing here. My logic is, that if everything goes well, return true and close the client because it is no longer needed. After a successful signup, there is redirect to another page where it connects to the database with another Pool with different privileges.
Apparently there is something wrong, regarding my use of client.end();
. Should promises not include it? Is it something else?
Thank you for your time
Issue Analytics
- State:
- Created 5 years ago
- Comments:5 (2 by maintainers)
If you use a pool you can likely avoid most of this as you never have to worry about calling
client.end()
. Just issue queries to the pool and deal with the results. If you can, it’s highly suggested to use a pool as it greatly simplifies things and does the right thing by default. For most non-transactional usage (i.e. most of a web request) it’s the right way to go and will be faster as well.If you’re manually managing clients, say to add transaction management, then you’ll need to call
client.end()
after you’re done with the connection to shut it down. That needs to be called regardless of whether the transaction is successful or errant. Otherwise you’ll leak connections.If you created a single client manually and are reusing it across requests then calling
.end()
will break your app as the client can’t be reused after its closed. You should be creating the client for each request, either directly or viapool.connect()
, then closing it or callingclient.release()
(if it’s pooled) when you’re done.All of this is much much easier with async / await +
pool.query()
:Can I just say, there are 3 different connections to the db, each one has different db privileges (front end user only selects, signup user selects and inserts on the user table and cms user selects, updates, inserts and . deletes on certain tables) . This is considered an extra security measure that , surprisingly, is not discussed very often.
@sehrope Thanks for the help, I understand a lot of things now, and my code makes more sense. In my cms I will use transactions, so I have to use Clients and you end up helping me a lot with your remarks.
Now, the structure is
Thank you for your time