From 5303656a694f137a66a5ad60681b48a33f54d837 Mon Sep 17 00:00:00 2001 From: Naoya Yoshizawa Date: Thu, 5 Mar 2026 15:28:31 +0900 Subject: [PATCH] fix(pg): prevent process crash during Aurora failover Two issues cause Node.js process to crash when an Aurora failover occurs: 1. AwsPgInternalPoolClient creates a pg.Pool without an 'error' event handler. During failover, idle connections are terminated by the server, emitting 'error' events on the pool. Without a handler, Node.js throws an uncaught exception and the process exits. 2. AwsPGPooledConnection.release() unconditionally calls this.targetClient.client.release(), but after failover the new client may not have a release() method (e.g., a direct connection rather than a pooled connection), causing a TypeError. Fix 1: Attach a no-op 'error' handler to the internal pg.Pool so idle connection errors are swallowed. The failover plugin handles reconnection. Fix 2: Check if release() exists on the underlying client before calling it. --- pg/lib/client.ts | 6 +++++- pg/lib/icp/pg_internal_pool_client.ts | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/pg/lib/client.ts b/pg/lib/client.ts index 4517e1659..264143b18 100644 --- a/pg/lib/client.ts +++ b/pg/lib/client.ts @@ -358,7 +358,11 @@ class AwsPGPooledConnection extends BaseAwsPgClient { throw new UndefinedClientError(); } this.pluginService.removeErrorListener(this.targetClient); - return await this.targetClient.client.release(); + // After failover, the new target client may not have a release() method + // (e.g., a direct connection instead of a pooled connection). + if (typeof this.targetClient.client?.release === "function") { + return await this.targetClient.client.release(); + } }, null ); diff --git a/pg/lib/icp/pg_internal_pool_client.ts b/pg/lib/icp/pg_internal_pool_client.ts index ed0324db1..e7d6c6128 100644 --- a/pg/lib/icp/pg_internal_pool_client.ts +++ b/pg/lib/icp/pg_internal_pool_client.ts @@ -25,6 +25,12 @@ export class AwsPgInternalPoolClient implements AwsInternalPoolClient { constructor(props: pkgPg.PoolConfig) { this.targetPool = new pkgPg.Pool(props); + // Handle idle client errors to prevent process crash during Aurora failover. + // When a failover occurs, idle connections in the pool are terminated by the server, + // which emits 'error' events. Without this handler, Node.js throws an uncaught exception. + this.targetPool.on("error", () => { + // Intentionally swallowed. The failover plugin will handle reconnection. + }); } async end(): Promise {