Files
Claude 6bb61cdbcc fix(db): ne plus arrêter le serveur quand Postgres coupe une connexion
Quand la base redémarre (redéploiement, restart du conteneur) ou que le
réseau coupe, pg-pool émet 'error' pour chaque connexion inactive
interrompue. Aucun écouteur n'était branché sur le pool de server/db.ts :
Node levait l'événement non géré et arrêtait tout le serveur, avec un
dump géant du client pg dans les logs. Le pool écarte déjà la connexion
fautive et en ouvre une neuve à la requête suivante : on se contente de
journaliser le code et le message.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MsDJjQrAggcJwbbBtKhgyb
2026-10-05 14:07:23 +00:00

70 lines
2.4 KiB
TypeScript

import * as schema from "@shared/schema";
// Simple environment detection
const isProduction = process.env.NODE_ENV === 'production';
const dbUrl = process.env.DATABASE_URL;
console.log('🔗 Database initialization:', {
NODE_ENV: process.env.NODE_ENV,
isProduction,
hasDbUrl: !!dbUrl,
dbHost: dbUrl ? new URL(dbUrl).hostname : 'none'
});
let db: any;
let pool: any;
if (isProduction && dbUrl && (dbUrl.includes('logiflow-db') || dbUrl.includes('localhost') || dbUrl.includes('127.0.0.1'))) {
// Standard PostgreSQL for production Docker
console.log('🐳 PRODUCTION: Using standard PostgreSQL');
const { Pool } = await import('pg');
const { drizzle } = await import('drizzle-orm/node-postgres');
pool = new Pool({
connectionString: dbUrl,
ssl: false,
max: 25, // Increased from 10 to handle concurrent verifications
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 15000, // Increased from 5000 to 15000
});
db = drizzle({ client: pool, schema });
// Une connexion inactive coupée par Postgres (redémarrage ou redéploiement de
// la base, coupure réseau) fait émettre 'error' au pool. Sans écouteur, Node
// arrête tout le serveur ; le pool écarte déjà la connexion fautive et en
// ouvre une neuve à la requête suivante, il suffit donc de journaliser.
pool.on('error', (err: any) => {
console.error('❌ PostgreSQL idle connection error (connexion écartée):', err?.code || '', err?.message);
});
// Test connection
try {
await pool.connect().then((client: any) => {
console.log('✅ PostgreSQL connection test successful');
client.release();
});
} catch (error) {
console.error('❌ PostgreSQL connection test failed:', error);
}
} else {
// Fallback: use Neon for development (but will be overridden by MemStorage)
console.log('🔧 DEV: Using Neon (fallback, will use MemStorage)');
const { Pool, neonConfig } = await import('@neondatabase/serverless');
const { drizzle } = await import('drizzle-orm/neon-serverless');
const ws = await import('ws');
neonConfig.webSocketConstructor = ws.default;
if (dbUrl) {
pool = new Pool({ connectionString: dbUrl });
db = drizzle({ client: pool, schema });
} else {
// Create dummy instances for development
pool = null;
db = null;
console.log('🔧 DEV: No DATABASE_URL, using MemStorage');
}
}
export { db, pool };