Fix: убран process.exit(1) — приложение не падает, показывает сообщение об ошибке. Версия 0.1.14
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ipwhitelist",
|
"name": "ipwhitelist",
|
||||||
"version": "0.1.13",
|
"version": "0.1.14",
|
||||||
"description": "IP WhiteList microservice for cloud provider",
|
"description": "IP WhiteList microservice for cloud provider",
|
||||||
"main": "server.js",
|
"main": "server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -61,23 +61,16 @@ async function start() {
|
|||||||
const { pool } = require('./src/db');
|
const { pool } = require('./src/db');
|
||||||
app.use(createSessionMiddleware(pool));
|
app.use(createSessionMiddleware(pool));
|
||||||
|
|
||||||
// ── Fail-fast в production ────────────────────────────────────────────────
|
// ── Fail-fast в production (без exit — сообщение в лог) ────────────────────
|
||||||
// Если секреты не заданы — приложение в проде немедленно падает.
|
|
||||||
// Дефолтные значения — только для локальной разработки.
|
|
||||||
if (process.env.NODE_ENV === 'production') {
|
|
||||||
const DEFAULT_SESSION = 'dev-session-secret-change-me';
|
const DEFAULT_SESSION = 'dev-session-secret-change-me';
|
||||||
if (!process.env.SESSION_SECRET || process.env.SESSION_SECRET === DEFAULT_SESSION) {
|
let fatalError = null;
|
||||||
console.error('FATAL: SESSION_SECRET не задан или равен дефолту в production!');
|
if (process.env.NODE_ENV === 'production') {
|
||||||
process.exit(1);
|
if (!process.env.SESSION_SECRET || process.env.SESSION_SECRET === DEFAULT_SESSION)
|
||||||
}
|
fatalError = 'SESSION_SECRET не задан или равен дефолту в production';
|
||||||
if (!process.env.DB_PASS) {
|
else if (!process.env.DB_PASS)
|
||||||
console.error('FATAL: DB_PASS не задан в production!');
|
fatalError = 'DB_PASS не задан в production';
|
||||||
process.exit(1);
|
else if (!process.env.CSRF_SECRET || process.env.CSRF_SECRET === 'dev-csrf-secret-change-in-prod')
|
||||||
}
|
fatalError = 'CSRF_SECRET не задан или равен дефолту в production';
|
||||||
if (!process.env.CSRF_SECRET || process.env.CSRF_SECRET === 'dev-csrf-secret-change-in-prod') {
|
|
||||||
console.error('FATAL: CSRF_SECRET не задан или равен дефолту в production!');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// k8s liveness + readiness probes
|
// k8s liveness + readiness probes
|
||||||
@@ -91,6 +84,15 @@ async function start() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Если фатальная ошибка конфигурации — показываем на всех страницах сообщение
|
||||||
|
if (fatalError) {
|
||||||
|
console.error(fatalError);
|
||||||
|
app.use((req, res) => {
|
||||||
|
res.status(503).type('html').send(errorPage(fatalError));
|
||||||
|
});
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
// JWKS endpoint для валидации токенов внешними сервисами (только в mock-режиме)
|
// JWKS endpoint для валидации токенов внешними сервисами (только в mock-режиме)
|
||||||
if (auth.jwksHandler) app.get('/.well-known/jwks.json', auth.jwksHandler);
|
if (auth.jwksHandler) app.get('/.well-known/jwks.json', auth.jwksHandler);
|
||||||
|
|
||||||
@@ -136,20 +138,24 @@ async function start() {
|
|||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
start()
|
start()
|
||||||
.then(a => {
|
.then(a => {
|
||||||
const server = a.listen(PORT, () => console.log('Server on port ' + PORT));
|
a.listen(PORT, () => console.log('Server on port ' + PORT));
|
||||||
// Graceful shutdown по SIGTERM (k8s)
|
// Graceful shutdown по SIGTERM (k8s)
|
||||||
process.on('SIGTERM', () => {
|
process.on('SIGTERM', () => {
|
||||||
console.log('SIGTERM — shutting down...');
|
console.log('SIGTERM — shutting down...');
|
||||||
server.close(() => {
|
|
||||||
console.log('HTTP closed');
|
|
||||||
const { pool } = require('./src/db');
|
const { pool } = require('./src/db');
|
||||||
pool.end().then(() => { console.log('DB pool closed'); process.exit(0); });
|
pool.end().then(() => { console.log('DB pool closed'); process.exit(0); });
|
||||||
});
|
|
||||||
setTimeout(() => { console.log('Forced exit'); process.exit(0); }, 10000);
|
setTimeout(() => { console.log('Forced exit'); process.exit(0); }, 10000);
|
||||||
});
|
});
|
||||||
return server;
|
|
||||||
})
|
})
|
||||||
.catch(e => { console.error('Startup error:', e); process.exit(1); });
|
.catch(e => {
|
||||||
|
console.error('Startup error:', e.message);
|
||||||
|
// Не падаем — запускаем HTTP с сообщением об ошибке
|
||||||
|
const errorApp = require('express')();
|
||||||
|
errorApp.use((req, res) => {
|
||||||
|
res.status(503).type('html').send('<html><head><meta charset="utf-8"><title>Авария</title></head><body style="font-family:sans-serif;padding:40px;text-align:center"><h1>⚙️ Сервис временно недоступен</h1><p>Причина: ' + (e.message || 'неизвестна') + '</p><p>Попробуйте обновить страницу через минуту</p></body></html>');
|
||||||
|
});
|
||||||
|
errorApp.listen(PORT, () => console.log('Server on port ' + PORT + ' (ERROR MODE)'));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { start };
|
module.exports = { start };
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
// ═══════════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
version: '0.1.13',
|
version: '0.1.14',
|
||||||
|
|
||||||
// ── Среда ─────────────────────────────────────────────────────────────────
|
// ── Среда ─────────────────────────────────────────────────────────────────
|
||||||
// APP_ENV=test → тестовый стенд (жёлтый баннер в UI, можно включать тестовый API)
|
// APP_ENV=test → тестовый стенд (жёлтый баннер в UI, можно включать тестовый API)
|
||||||
|
|||||||
Reference in New Issue
Block a user