fix(GRO-2652): retry DB query in initAuth on transient ECONNRESET
The auth_provider_config DB query at boot has no error handling; a transient ECONNRESET causes authInitPromise to reject, propagating to the top-level await initAuth() and crashing the process (exit 1). Add up to 5 retry attempts with exponential backoff (1 s, 2 s, 4 s, 8 s) so a single connection reset does not abort initialization. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
+17
-2
@@ -124,13 +124,28 @@ export async function initAuth(): Promise<void> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 1: Try to load config from DB
|
// Step 1: Try to load config from DB, with retry-with-backoff for transient ECONNRESET (GRO-2652).
|
||||||
|
// A single connection reset during boot must not abort initialization.
|
||||||
const db = getDb();
|
const db = getDb();
|
||||||
const [dbConfig] = await db
|
let dbQueryRows: (typeof authProviderConfig.$inferSelect)[] = [];
|
||||||
|
let dbAttempt = 0;
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
dbQueryRows = await db
|
||||||
.select()
|
.select()
|
||||||
.from(authProviderConfig)
|
.from(authProviderConfig)
|
||||||
.where(eq(authProviderConfig.enabled, true))
|
.where(eq(authProviderConfig.enabled, true))
|
||||||
.limit(1);
|
.limit(1);
|
||||||
|
break;
|
||||||
|
} catch (err) {
|
||||||
|
dbAttempt++;
|
||||||
|
if (dbAttempt >= 5) throw err;
|
||||||
|
const delay = Math.min(1000 * 2 ** (dbAttempt - 1), 8_000);
|
||||||
|
console.warn(`[auth] DB query attempt ${dbAttempt} failed (${err}), retrying in ${delay}ms`);
|
||||||
|
await new Promise((r) => setTimeout(r, delay));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const [dbConfig] = dbQueryRows;
|
||||||
|
|
||||||
let providerConfig: {
|
let providerConfig: {
|
||||||
providerId: string;
|
providerId: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user