From d0b3b73fe4fc7ab930f5aa83ddcf26dd6f7aca46 Mon Sep 17 00:00:00 2001 From: devin ivy Date: Wed, 16 Aug 2023 14:02:42 -0400 Subject: [PATCH] Handle db client errors on appview (#1481) handle db client errors on bav --- packages/bsky/src/db/db.ts | 4 ++++ packages/bsky/tests/db.test.ts | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/packages/bsky/src/db/db.ts b/packages/bsky/src/db/db.ts index 7c984892ea1..51787023f20 100644 --- a/packages/bsky/src/db/db.ts +++ b/packages/bsky/src/db/db.ts @@ -3,6 +3,7 @@ import { Kysely, PostgresDialect } from 'kysely' import { Pool as PgPool, types as pgTypes } from 'pg' import DatabaseSchema, { DatabaseSchemaType } from './database-schema' import { PgOptions } from './types' +import { dbLogger } from '../logger' export class Database { pool: PgPool @@ -41,6 +42,7 @@ export class Database { } pool.on('connect', (client) => { + client.on('error', onClientError) // Used for trigram indexes, e.g. on actor search client.query('SET pg_trgm.word_similarity_threshold TO .4;') if (schema) { @@ -83,3 +85,5 @@ export class Database { } export default Database + +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 565f07a0e73..5f92a515586 100644 --- a/packages/bsky/tests/db.test.ts +++ b/packages/bsky/tests/db.test.ts @@ -1,4 +1,5 @@ import { once } from 'events' +import { sql } from 'kysely' import { wait } from '@atproto/common' import { TestNetwork } from '@atproto/dev-env' import { Database } from '../src' @@ -20,6 +21,19 @@ describe('db', () => { await network.close() }) + it('handles client errors without crashing.', async () => { + const tryKillConnection = db.transaction(async (dbTxn) => { + const result = await sql`select pg_backend_pid() as pid;`.execute( + dbTxn.db, + ) + const pid = result.rows[0]?.['pid'] as number + await sql`select pg_terminate_backend(${pid});`.execute(db.db) + await sql`select 1;`.execute(dbTxn.db) + }) + // This should throw, but no unhandled error + await expect(tryKillConnection).rejects.toThrow() + }) + describe('transaction()', () => { it('commits changes', async () => { const result = await db.transaction(async (dbTxn) => {