Skip to content

Commit f9e88cb

Browse files
authored
fix: include more types of pg connection errors in startup retry logic (#1051)
1 parent 87596c7 commit f9e88cb

File tree

1 file changed

+35
-20
lines changed

1 file changed

+35
-20
lines changed

src/datastore/postgres-store.ts

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,36 @@ export async function dangerousDropAllTables(opts?: {
288288
}
289289
}
290290

291+
/**
292+
* Checks if a given error from the pg lib is a connection error (i.e. the query is retryable).
293+
* If true then returns a normalized error message, otherwise returns false.
294+
*/
295+
function isPgConnectionError(error: any): string | false {
296+
if (error.code === 'ECONNREFUSED') {
297+
return 'Postgres connection ECONNREFUSED';
298+
} else if (error.code === 'ETIMEDOUT') {
299+
return 'Postgres connection ETIMEDOUT';
300+
} else if (error.code === 'ENOTFOUND') {
301+
return 'Postgres connection ENOTFOUND';
302+
} else if (error.message) {
303+
const msg = (error as Error).message.toLowerCase();
304+
if (msg.includes('database system is starting up')) {
305+
return 'Postgres connection failed while database system is starting up';
306+
} else if (msg.includes('database system is shutting down')) {
307+
return 'Postgres connection failed while database system is shutting down';
308+
} else if (msg.includes('connection terminated unexpectedly')) {
309+
return 'Postgres connection terminated unexpectedly';
310+
} else if (msg.includes('connection terminated')) {
311+
return 'Postgres connection terminated';
312+
} else if (msg.includes('connection error')) {
313+
return 'Postgres client has encountered a connection error and is not queryable';
314+
} else if (msg.includes('terminating connection due to unexpected postmaster exit')) {
315+
return 'Postgres connection terminating due to unexpected postmaster exit';
316+
}
317+
}
318+
return false;
319+
}
320+
291321
/**
292322
* @deprecated use `txColumns()` instead.
293323
*/
@@ -776,21 +806,9 @@ export class PgDataStore
776806
return client;
777807
} catch (error: any) {
778808
// Check for transient errors, and retry after 1 second
779-
if (error.code === 'ECONNREFUSED') {
780-
logger.warn(`Postgres connection ECONNREFUSED, will retry, attempt #${retryAttempts}`);
781-
await timeout(1000);
782-
} else if (error.code === 'ETIMEDOUT') {
783-
logger.warn(`Postgres connection ETIMEDOUT, will retry, attempt #${retryAttempts}`);
784-
await timeout(1000);
785-
} else if (error.message === 'the database system is starting up') {
786-
logger.warn(
787-
`Postgres connection failed while database system is restarting, will retry, attempt #${retryAttempts}`
788-
);
789-
await timeout(1000);
790-
} else if (error.message === 'Connection terminated unexpectedly') {
791-
logger.warn(
792-
`Postgres connection terminated unexpectedly, will retry, attempt #${retryAttempts}`
793-
);
809+
const pgConnectionError = isPgConnectionError(error);
810+
if (pgConnectionError) {
811+
logger.warn(`${pgConnectionError}, will retry, attempt #${retryAttempts}`);
794812
await timeout(1000);
795813
} else {
796814
throw error;
@@ -2583,11 +2601,8 @@ export class PgDataStore
25832601
connectionOkay = true;
25842602
break;
25852603
} catch (error: any) {
2586-
if (
2587-
error.code !== 'ECONNREFUSED' &&
2588-
error.message !== 'Connection terminated unexpectedly' &&
2589-
!error.message?.includes('database system is starting')
2590-
) {
2604+
const pgConnectionError = isPgConnectionError(error);
2605+
if (!pgConnectionError) {
25912606
logError('Cannot connect to pg', error);
25922607
throw error;
25932608
}

0 commit comments

Comments
 (0)