From dc3c23055a4c7199a7411a7944e33096214e5bdf Mon Sep 17 00:00:00 2001 From: Flea Flicker Date: Sun, 24 May 2026 19:46:23 +0000 Subject: [PATCH] fix(api): add timeouts for OIDC discovery fetch and DB connection - OIDC discovery fetch in initAuth() now has a 5s AbortSignal.timeout to fail fast instead of hanging indefinitely when the auth server is unreachable. This was identified as a root cause of startup ECONNRESET crashes on UAT where ztunnel drops TCP connections before headers arrive. - DB postgres client now sets connect_timeout: 5 so failed connection attempts fail fast rather than hanging the startup sequence. - Graceful shutdown timeout tightened to 8s (from 10s) to avoid getting killed by Kubernetes liveness-probe deadline while draining. Fixes GRO-1678. Co-Authored-By: Paperclip --- packages/db/src/index.ts | 2 +- src/index.ts | 10 ++++++---- src/lib/auth.ts | 4 +++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/db/src/index.ts b/packages/db/src/index.ts index 8b3b01f..e3bc914 100644 --- a/packages/db/src/index.ts +++ b/packages/db/src/index.ts @@ -12,7 +12,7 @@ export function getDb() { if (_db) return _db; const url = process.env.DATABASE_URL; if (!url) throw new Error("DATABASE_URL is not set"); - const client = postgres(url, { max: 10 }); + const client = postgres(url, { max: 10, connect_timeout: 5 }); _db = drizzle(client, { schema }); return _db; } diff --git a/src/index.ts b/src/index.ts index 9ae50b8..2e8055e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -282,14 +282,16 @@ startReminderScheduler(); function shutdown() { console.log("Shutting down gracefully..."); + // SIGTERM/SIGINT → server.close() → callback → process.exit(0) + // If graceful close takes >8s, force-exit to avoid being killed undrained + setTimeout(() => { + console.error("Graceful close timeout — forcing exit"); + process.exit(1); + }, 8_000); server.close(() => { console.log("HTTP server closed"); process.exit(0); }); - setTimeout(() => { - console.error("Forced shutdown after timeout"); - process.exit(1); - }, 10_000); } process.on("SIGTERM", shutdown); diff --git a/src/lib/auth.ts b/src/lib/auth.ts index 9e78740..da2b2d1 100644 --- a/src/lib/auth.ts +++ b/src/lib/auth.ts @@ -186,7 +186,9 @@ export async function initAuth(): Promise { const discoveryUrlStr = `${providerConfig.issuerUrl}/.well-known/openid-configuration`; let oidcConfig: Record = {}; try { - const discoveryRes = await fetch(discoveryUrlStr); + const discoveryRes = await fetch(discoveryUrlStr, { + signal: AbortSignal.timeout(5000), + }); if (discoveryRes.ok) { const discovery = await discoveryRes.json() as { authorization_endpoint?: string; -- 2.52.0