diff --git a/index.js b/index.js index e517f76f..1c7faf21 100644 --- a/index.js +++ b/index.js @@ -316,13 +316,31 @@ class Pool extends EventEmitter { } const response = promisify(this.Promise, cb) cb = response.callback + this.connect((err, client) => { if (err) { return cb(err) } + + let clientReleased = false + const onError = (err) => { + if (clientReleased) { + return + } + clientReleased = true + client.release(err) + cb(err) + } + + client.once('error', onError) this.log('dispatching query') client.query(text, values, (err, res) => { this.log('query dispatched') + client.removeListener('error', onError) + if (clientReleased) { + return + } + clientReleased = true client.release(err) if (err) { return cb(err) diff --git a/test/error-handling.js b/test/error-handling.js index 1e416683..9ef8848e 100644 --- a/test/error-handling.js +++ b/test/error-handling.js @@ -226,4 +226,19 @@ describe('pool error handling', function () { }) }) }) + + it('handles post-checkout client failures in pool.query', (done) => { + const pool = new Pool({ max: 1 }) + pool.on('error', () => { + // We double close the connection in this test, prevent exception caused by that + }) + pool.query('SELECT pg_sleep(5)', [], (err) => { + expect(err).to.be.an(Error) + done() + }) + + setTimeout(() => { + pool._clients[0].end() + }, 1000) + }) })