diff --git a/packages/bsky/src/db/db.ts b/packages/bsky/src/db/db.ts index 51787023f20..cb58eb4742b 100644 --- a/packages/bsky/src/db/db.ts +++ b/packages/bsky/src/db/db.ts @@ -41,6 +41,7 @@ export class Database { throw new Error(`Postgres schema must only contain [A-Za-z_]: ${schema}`) } + pool.on('error', onPoolError) pool.on('connect', (client) => { client.on('error', onClientError) // Used for trigram indexes, e.g. on actor search @@ -86,4 +87,5 @@ export class Database { export default Database +const onPoolError = (err: Error) => dbLogger.error({ err }, 'db pool error') const onClientError = (err: Error) => dbLogger.error({ err }, 'db client error') diff --git a/packages/bsky/tests/db.test.ts b/packages/bsky/tests/db.test.ts index 5f92a515586..bb7562e9a92 100644 --- a/packages/bsky/tests/db.test.ts +++ b/packages/bsky/tests/db.test.ts @@ -34,6 +34,17 @@ describe('db', () => { await expect(tryKillConnection).rejects.toThrow() }) + it('handles pool errors without crashing.', async () => { + const conn1 = await db.pool.connect() + const conn2 = await db.pool.connect() + const result = await conn1.query('select pg_backend_pid() as pid;') + const conn1pid: number = result.rows[0].pid + conn1.release() + await wait(100) // let release apply, conn is now idle on pool. + await conn2.query(`select pg_terminate_backend(${conn1pid});`) + conn2.release() + }) + describe('transaction()', () => { it('commits changes', async () => { const result = await db.transaction(async (dbTxn) => {