Skip to content

Commit

Permalink
Cursor: avoid closing connection twice if error received after destroy()
Browse files Browse the repository at this point in the history
  • Loading branch information
alxndrsn committed Oct 6, 2022
1 parent 9dfb3dc commit 63e1515
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
3 changes: 3 additions & 0 deletions packages/pg-cursor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ class Cursor extends EventEmitter {
}

handleError(msg) {
// If this cursor has already closed, don't try to handle the error.
if(this.state === 'done') return;

// If we're in an initialized state we've never been submitted
// and don't have a connection instance reference yet.
// This can happen if you queue a stream and close the client before
Expand Down
42 changes: 42 additions & 0 deletions packages/pg-query-stream/test/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,46 @@ describe('error recovery', () => {
await client.end()
})
})

it('should work if used after timeout error', async () => {
const pool = new Pool({ max: 1, connectionTimeoutMillis: 400, statement_timeout: 400 });

const res1 = await pool.query('SELECT 1 AS a');
assert.deepStrictEqual(res1.rows, [ { a:1 } ]);

const query = new QueryStream('SELECT 2 AS b');
const client = await pool.connect();
const stream = await client.query(query);

await assert.rejects(() => pool.query('SELECT TRUE'), { message: 'timeout exceeded when trying to connect' });

await stream.destroy();
await client.release();

const res2 = await pool.query('SELECT 4 AS d');
assert.deepStrictEqual(res2.rows, [ { d:4 } ]);

await pool.end();
})

it('should work if used after syntax error', async () => {
const pool = new Pool({ max: 1, statement_timeout: 100 }); // statement_timeout is required here, so maybe this is just another timeout error?

const res1 = await pool.query('SELECT 1 AS a');
assert.deepStrictEqual(res1.rows, [ { a:1 } ]);

const query = new QueryStream('SELECT 2 AS b');
const client = await pool.connect();
const stream = await client.query(query);

await new Promise(resolve => setTimeout(resolve, 10));

await stream.destroy();
await client.release();

const res2 = await pool.query('SELECT 4 AS d');
assert.deepStrictEqual(res2.rows, [ { d:4 } ]);

await pool.end();
})
})

0 comments on commit 63e1515

Please sign in to comment.