From 095efb1cca2b32662ae9d62f8337b4eb398023a5 Mon Sep 17 00:00:00 2001 From: Flea Flicker <22+gb_flea@noreply.git.farh.net> Date: Wed, 5 Aug 2026 08:21:14 +0000 Subject: [PATCH] fix(GRO-2652): start server before initAuth; retry auth init on ECONNRESET MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously: await initAuth() was a top-level ESM await. Any boot-time ECONNRESET from Postgres propagated as an uncaught module-evaluation error and killed the process before the server even started. Now: - serve() starts immediately so /health and public routes are available - initAuth() runs in a retry loop (up to 10 attempts, exponential 500 ms → 30 s); a permanent failure degrades to 503 on auth routes (existing catch-to-503 in authRouter) rather than crashing the pod Co-Authored-By: Paperclip --- src/index.ts | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 6c0c930..e08a2ff 100644 --- a/src/index.ts +++ b/src/index.ts @@ -292,14 +292,34 @@ api.route("/search", searchRouter); api.route("/buffer-rules", bufferRulesRouter); api.route("/routes", routesRouter); +// Start the HTTP server first so /health and public routes are available immediately. +// Auth initialization runs afterward with retry — a transient DB ECONNRESET at boot +// must not crash the process (GRO-2652). Auth routes return 503 until initAuth succeeds. const port = Number(process.env.PORT ?? 3000); -await initAuth(); -console.log(`API server listening on port ${port}`); const server = serve({ fetch: app.fetch, port }); +console.log(`API server listening on port ${port}`); // Start background reminder scheduler (runs every minute to check for upcoming appointments) startReminderScheduler(); +let initAttempt = 0; +while (true) { + try { + await initAuth(); + break; + } catch (err) { + initAttempt++; + const delay = Math.min(2 ** initAttempt * 500, 30_000); + console.error(`[auth] initAuth attempt ${initAttempt} failed: ${err}`); + if (initAttempt >= 10) { + console.error("[auth] auth init permanently failed — auth endpoints will serve 503"); + break; + } + console.error(`[auth] retrying in ${delay}ms`); + await new Promise((r) => setTimeout(r, delay)); + } +} + function shutdown() { console.log("Shutting down gracefully..."); // SIGTERM/SIGINT → server.close() → callback → process.exit(0)