Skip to content

Commit 01e6420

Browse files
authored
Fix TypeError: Cannot read properties of undefined (reading 'isActive') (#881)
This error occurs in situations where the pool was already close, the acquire resource was already completed and a pool was recreated in the meantime. In this situation, the _release method is called again but with an empty pool state causing the error. For solving this issue, we should check if the state is defined before check the `isActive`. Undefined poolState should be considered closed in this case and the connection should be detroyed.
1 parent 14f0d65 commit 01e6420

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

packages/bolt-connection/src/pool/pool.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ class Pool {
251251
const key = address.asKey()
252252
const pool = this._pools[key]
253253

254-
if (pool && poolState.isActive()) {
254+
if (pool && poolState && poolState.isActive()) {
255255
// there exist idle connections for the given key
256256
if (!this._validate(resource)) {
257257
if (this._log.isDebugEnabled()) {

packages/bolt-connection/test/pool/pool.test.js

+46
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,52 @@ describe('#unit Pool', () => {
275275
expect(r1.destroyed).toBeFalsy()
276276
})
277277

278+
it('people are strange', async () => {
279+
let counter = 0
280+
const address = ServerAddress.fromUrl('bolt://localhost:7687')
281+
const pool = new Pool({
282+
create: (server, release) =>
283+
Promise.resolve(new Resource(server, counter++, release)),
284+
destroy: res => {
285+
res.destroyed = true
286+
return Promise.resolve()
287+
},
288+
config: new PoolConfig(2, 500)
289+
})
290+
291+
// Acquire resource
292+
const r0 = await pool.acquire(address)
293+
expect(pool.has(address)).toBeTruthy()
294+
expect(r0.id).toEqual(0)
295+
296+
// Purging the key
297+
await pool.purge(address)
298+
expect(pool.has(address)).toBeFalsy()
299+
expect(r0.destroyed).toBeFalsy()
300+
301+
// Acquiring second resource should recreate the pool
302+
const r1 = await pool.acquire(address)
303+
304+
const r2 = pool.acquire(address)
305+
306+
307+
setTimeout(async () => {
308+
pool._poolState = {}
309+
await r0.close()
310+
}, 700)
311+
312+
313+
try {
314+
await r2
315+
expect(false).toBeTruthy()
316+
} catch(e) {
317+
expect(e.message).toEqual('Connection acquisition timed out in 500 ms. Pool status: Active conn count = 2, Idle conn count = 0.')
318+
}
319+
320+
await r1.close()
321+
await pool.close()
322+
})
323+
278324
it('close purges all keys', async () => {
279325
let counter = 0
280326

0 commit comments

Comments
 (0)