From 5cb957959b5181468278e99463f110082f5f90e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20W=C3=BCrbach?= Date: Mon, 11 Feb 2019 21:18:53 +0100 Subject: [PATCH] Prevent requeuing a broken client If a client is not queryable, the pool should prevent requeuing instead of strictly enforcing errors to be propagated back to it. --- index.js | 2 +- test/error-handling.js | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index cfe377c..fafde78 100644 --- a/index.js +++ b/index.js @@ -30,7 +30,7 @@ function throwOnRelease () { function release (client, err) { client.release = throwOnRelease - if (err || this.ending) { + if (err || this.ending || !client._queryable || client._ending) { this._remove(client) this._pulseQueue() return diff --git a/test/error-handling.js b/test/error-handling.js index e899c35..4923c9d 100644 --- a/test/error-handling.js +++ b/test/error-handling.js @@ -124,6 +124,40 @@ describe('pool error handling', function () { }) }) + describe('releasing a not queryable client', () => { + it('removes the client from the pool', (done) => { + const pool = new Pool({ max: 1 }) + const connectionError = new Error('connection failed') + + pool.once('error', () => { + // Ignore error on pool + }) + + pool.connect((err, client) => { + expect(err).to.be(undefined) + + client.once('error', (err) => { + expect(err).to.eql(connectionError) + + // Releasing the client should remove it from the pool, + // whether called with an error or not + client.release() + + // Verify that the pool is still usuable and new client has been + // created + pool.query('SELECT $1::text as name', ['brianc'], (err, res) => { + expect(err).to.be(undefined) + expect(res.rows).to.eql([{ name: 'brianc' }]) + + pool.end(done) + }) + }) + + client.emit('error', connectionError) + }) + }) + }) + describe('pool with lots of errors', () => { it('continues to work and provide new clients', co.wrap(function * () { const pool = new Pool({ max: 1 })