diff --git a/packages/pg/lib/client.js b/packages/pg/lib/client.js index 93807e48c..05efbdc5a 100644 --- a/packages/pg/lib/client.js +++ b/packages/pg/lib/client.js @@ -545,7 +545,7 @@ Client.prototype.query = function (config, values, callback) { Client.prototype.end = function (cb) { this._ending = true - if (this.activeQuery) { + if (this.activeQuery || !this._queryable) { // if we have an active query we need to force a disconnect // on the socket - otherwise a hung query could block end forever this.connection.stream.destroy() diff --git a/packages/pg/test/integration/connection-pool/error-tests.js b/packages/pg/test/integration/connection-pool/error-tests.js index 597c29b38..9fe760431 100644 --- a/packages/pg/test/integration/connection-pool/error-tests.js +++ b/packages/pg/test/integration/connection-pool/error-tests.js @@ -1,6 +1,7 @@ 'use strict' var helper = require('./test-helper') const pg = helper.pg +const native = helper.args.native const suite = new helper.Suite() suite.test('connecting to invalid port', (cb) => { @@ -99,3 +100,31 @@ suite.test('connection-level errors cause future queries to fail', (cb) => { })) })) }) + +suite.test('handles socket error during pool.query and destroys it immediately', (cb) => { + const pool = new pg.Pool({ max: 1 }) + + if (native) { + pool.query('SELECT pg_sleep(10)', [], (err) => { + assert.equal(err.message, 'canceling statement due to user request') + cb() + }) + + setTimeout(() => { + pool._clients[0].native.cancel((err) => { + assert.ifError(err) + }) + }, 100) + } else { + pool.query('SELECT pg_sleep(10)', [], (err) => { + assert.equal(err.message, 'network issue') + assert.equal(stream.destroyed, true) + cb() + }) + + const stream = pool._clients[0].connection.stream + setTimeout(() => { + stream.emit('error', new Error('network issue')) + }, 100) + } +})