diff --git a/src/framework/config/env.ts b/src/framework/config/env.ts index d4b00bd..ad5f6ee 100644 --- a/src/framework/config/env.ts +++ b/src/framework/config/env.ts @@ -8,7 +8,11 @@ loadEnv(); const envSchema = z.object({ DISCORD_TOKEN: z.string().min(1, "DISCORD_TOKEN is required"), DISCORD_CLIENT_ID: z.string().min(1, "DISCORD_CLIENT_ID is required"), - DATABASE_URL: z.string().optional().transform((value) => value && value.length > 0 ? value : undefined), + DATABASE_URL: z + .string() + .trim() + .min(1, "DATABASE_URL is required") + .url("DATABASE_URL must be a valid URL"), DATABASE_SSL: z .string() .optional() diff --git a/src/framework/presence/presenceStore.ts b/src/framework/presence/presenceStore.ts index e9e7752..c159140 100644 --- a/src/framework/presence/presenceStore.ts +++ b/src/framework/presence/presenceStore.ts @@ -165,19 +165,22 @@ export const initPresenceStore = async (): Promise => { return store; } - if (!env.DATABASE_URL) { - throw new Error("DATABASE_URL is required to initialize PostgreSQL presence storage."); - } - const pool = new Pool({ connectionString: env.DATABASE_URL, ssl: env.DATABASE_SSL ? { rejectUnauthorized: false } : undefined, }); const nextStore = new PresenceStore(pool); - await nextStore.init(); - store = nextStore; - return nextStore; + try { + await nextStore.init(); + store = nextStore; + return nextStore; + } catch (error) { + await pool.end().catch(() => { + // Ignore close errors; the original init error is the one we want to surface. + }); + throw error; + } }; export const getPresenceStore = (): PresenceStore => { diff --git a/src/index.ts b/src/index.ts index a91bfad..0fbf1dd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -94,10 +94,10 @@ const bootstrap = async (): Promise => { await client.login(env.DISCORD_TOKEN); }; -bootstrap().catch((error) => { +bootstrap().catch(async (error) => { console.error("[boot] fatal error", error); - void shutdownPresenceStore().catch((closeError) => { + await shutdownPresenceStore().catch((closeError) => { console.error("[boot] failed to close presence store", closeError); }); - process.exitCode = 1; + process.exit(1); });