-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
87 lines (71 loc) · 3.22 KB
/
Copy pathserver.js
File metadata and controls
87 lines (71 loc) · 3.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
require("dotenv").config();
const validateEnv = require("./src/config/validateEnv");
const logger = require("./src/utils/logger");
// ─── Fail fast: validate environment before touching anything else ─────────
validateEnv();
const app = require("./src/app");
const connectToDB = require("./src/config/db");
const PORT = process.env.PORT || 3000;
/* ─────────────────────────────────────────────────────────────────────────
PROCESS-LEVEL ERROR GUARDS
Without these, any uncaught exception or unhandled rejection silently
crashes the process in production — no error logged, no graceful shutdown.
In Fintech this is critical: an in-flight transaction could be left PENDING
with no compensating action if the process dies without cleanup.
───────────────────────────────────────────────────────────────────────── */
process.on("uncaughtException", (err) => {
logger.error("UNCAUGHT EXCEPTION — shutting down", {
error: err.message,
stack: err.stack,
});
// Give the logger a moment to flush, then exit non-zero
setTimeout(() => process.exit(1), 500);
});
process.on("unhandledRejection", (reason, promise) => {
logger.error("UNHANDLED REJECTION — shutting down", {
reason: reason?.message || reason,
stack: reason?.stack,
});
setTimeout(() => process.exit(1), 500);
});
/* ─────────────────────────────────────────────────────────────────────────
GRACEFUL SHUTDOWN
On SIGTERM (sent by Docker/Kubernetes during a rolling deploy), stop
accepting new connections and let in-flight requests finish.
───────────────────────────────────────────────────────────────────────── */
let server;
connectToDB()
.then(() => {
logger.info("Connected to MongoDB");
server = app.listen(PORT, () => {
logger.info(`Server is running on port ${PORT}`, {
env: process.env.NODE_ENV || "development",
port: PORT,
});
});
})
.catch((err) => {
logger.error("Error connecting to MongoDB", {
error: err.message,
hint: "Verify MONGO_URI and network/DNS access for MongoDB Atlas.",
});
process.exit(1);
});
function gracefulShutdown(signal) {
logger.info(`${signal} received — starting graceful shutdown`);
if (server) {
server.close(() => {
logger.info("HTTP server closed");
process.exit(0);
});
// Force exit if graceful shutdown takes too long
setTimeout(() => {
logger.error("Graceful shutdown timeout — forcing exit");
process.exit(1);
}, 10000);
} else {
process.exit(0);
}
}
process.on("SIGTERM", () => gracefulShutdown("SIGTERM"));
process.on("SIGINT", () => gracefulShutdown("SIGINT"));