Skip to content

Commit bd87cdd

Browse files
committed
Fix connection / disconnection issues
1 parent 729d4e9 commit bd87cdd

File tree

5 files changed

+62
-40
lines changed

5 files changed

+62
-40
lines changed

lib/client.js

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,35 @@ Client.prototype.connect = function(callback) {
109109
self.secretKey = msg.secretKey;
110110
});
111111

112+
const connectingErrorHandler = (err) => {
113+
if (this._connectionError) {
114+
return;
115+
}
116+
this._connectionError = true
117+
if (callback) {
118+
return callback(err)
119+
}
120+
this.emit('error', err)
121+
}
122+
123+
const connectedErrorHandler = (err) => {
124+
if(this.activeQuery) {
125+
var activeQuery = self.activeQuery;
126+
this.activeQuery = null;
127+
return activeQuery.handleError(err, con);
128+
}
129+
this.emit('error', err)
130+
}
131+
132+
con.on('error', connectingErrorHandler)
133+
112134
//hook up query handling events to connection
113135
//after the connection initially becomes ready for queries
114136
con.once('readyForQuery', function() {
115137
self._connecting = false;
116138
self._attachListeners(con);
117-
139+
con.removeListener('error', connectingErrorHandler);
140+
con.on('error', connectedErrorHandler)
118141

119142
//process possible callback argument to Client#connect
120143
if (callback) {
@@ -136,37 +159,7 @@ Client.prototype.connect = function(callback) {
136159
self._pulseQueryQueue();
137160
});
138161

139-
con.on('error', function(error) {
140-
if(this.activeQuery) {
141-
var activeQuery = self.activeQuery;
142-
this.activeQuery = null;
143-
return activeQuery.handleError(error, con);
144-
}
145-
146-
if (this._connecting) {
147-
// set a flag indicating we've seen an error during connection
148-
// the backend will terminate the connection and we don't want
149-
// to throw a second error when the connection is terminated
150-
this._connectionError = true;
151-
}
152-
153-
if(!callback) {
154-
return this.emit('error', error);
155-
}
156-
157-
con.end(); // make sure ECONNRESET errors don't cause error events
158-
callback(error);
159-
callback = null;
160-
}.bind(this));
161-
162-
con.once('end', function() {
163-
if (callback) {
164-
// haven't received a connection message yet!
165-
var err = new Error('Connection terminated');
166-
callback(err);
167-
callback = null;
168-
return;
169-
}
162+
con.once('end', () => {
170163
if(this.activeQuery) {
171164
var disconnectError = new Error('Connection terminated');
172165
this.activeQuery.handleError(disconnectError, con);
@@ -177,12 +170,19 @@ Client.prototype.connect = function(callback) {
177170
// on this client then we have an unexpected disconnection
178171
// treat this as an error unless we've already emitted an error
179172
// during connection.
180-
if (!this._connectionError) {
181-
this.emit('error', new Error('Connection terminated unexpectedly'));
173+
const error = new Error('Connection terminated unexpectedly')
174+
if (this._connecting && !this._connectionError) {
175+
if (callback) {
176+
callback(error)
177+
} else {
178+
this.emit('error', error)
179+
}
180+
} else if (!this._connectionError) {
181+
this.emit('error', error);
182182
}
183183
}
184184
this.emit('end');
185-
}.bind(this));
185+
});
186186

187187

188188
con.on('notice', function(msg) {

test/integration/client/error-handling-tests.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
"use strict";
2-
"use strict";
32

43
var helper = require('./test-helper');
54
var util = require('util');
65

76
var pg = helper.pg
7+
const Client = pg.Client
88

99
var createErorrClient = function() {
1010
var client = helper.client();
@@ -84,6 +84,7 @@ suite.test('non-query error with callback', function(done) {
8484
user:'asldkfjsadlfkj'
8585
});
8686
client.connect(assert.calls(function(error, client) {
87+
console.log('error!', error.stack)
8788
assert(error instanceof Error)
8889
done()
8990
}));
@@ -142,3 +143,19 @@ suite.test('within a simple query', (done) => {
142143
done();
143144
});
144145
});
146+
147+
suite.test('connected, idle client error', (done) => {
148+
const client = new Client()
149+
client.connect((err) => {
150+
if (err) {
151+
throw new Error('Should not receive error callback after connection')
152+
}
153+
setImmediate(() => {
154+
(client.connection || client.native).emit('error', new Error('expected'))
155+
})
156+
})
157+
client.on('error', (err) => {
158+
assert.equal(err.message, 'expected')
159+
client.end(done)
160+
})
161+
})

test/integration/connection-pool/error-tests.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ pg.defaults.poolSize = 2;
88
const pool = new pg.Pool()
99

1010
const suite = new helper.Suite()
11+
suite.test('connecting to invalid port', (cb) => {
12+
const pool = new pg.Pool({ port: 13801 })
13+
pool.connect().catch(e => cb())
14+
})
15+
1116
suite.test('errors emitted on pool', (cb) => {
1217
//get first client
1318
pool.connect(assert.success(function (client, done) {

test/integration/test-helper.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
"use strict";
2-
var helper = require(__dirname + '/../test-helper');
2+
var helper = require('./../test-helper');
33

44
if(helper.args.native) {
5-
Client = require(__dirname + '/../../lib/native');
5+
Client = require('./../../lib/native');
66
helper.Client = Client;
77
helper.pg = helper.pg.native;
88
}

test/unit/client/early-disconnect-tests.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"use strict";
2-
var helper = require(__dirname + '/test-helper');
2+
var helper = require('./test-helper');
33
var net = require('net');
4-
var pg = require('../../..//lib/index.js');
4+
var pg = require('../../../lib/index.js');
55

66
/* console.log() messages show up in `make test` output. TODO: fix it. */
77
var server = net.createServer(function(c) {

0 commit comments

Comments
 (0)