Graceful shutdown helps your Node.js app close safely when errors happen. It stops new work, finishes current tasks, and cleans up before exiting.
Graceful shutdown on errors in Node.js
Start learning this pattern below
Jump into concepts and practice - no test required
process.on('uncaughtException', (err) => { // handle error // clean up resources process.exit(1); }); process.on('SIGTERM', () => { // clean up and exit process.exit(0); });
process.on listens for system signals or errors.
Always clean up resources like database connections before exiting.
process.on('uncaughtException', (err) => { console.error('Error caught:', err); // close server or DB here process.exit(1); });
process.on('SIGINT', () => { console.log('SIGINT received, shutting down...'); // clean up process.exit(0); });
async function shutdown() { await db.close(); console.log('Database closed'); process.exit(0); } process.on('SIGTERM', shutdown);
This Node.js server listens on port 3000. If you visit /error, it throws an error. The uncaughtException handler catches it, logs the message, closes the server, then exits with code 1. Pressing Ctrl+C triggers SIGINT to close the server gracefully and exit with code 0.
import http from 'node:http'; const server = http.createServer((req, res) => { if (req.url === '/error') { throw new Error('Simulated error'); } res.end('Hello World'); }); server.listen(3000, () => { console.log('Server running on http://localhost:3000'); }); process.on('uncaughtException', (err) => { console.error('Uncaught Exception:', err.message); server.close(() => { console.log('Server closed'); process.exit(1); }); }); process.on('SIGINT', () => { console.log('SIGINT received, shutting down server'); server.close(() => { console.log('Server closed'); process.exit(0); }); });
Never ignore errors; always handle them to avoid crashes.
Use server.close() to stop accepting new connections before exit.
Exiting with code 0 means success; non-zero means error.
Graceful shutdown stops new work and cleans up before exiting.
Use process.on to catch errors and signals.
Always close servers and resources before exiting.
Practice
Solution
Step 1: Understand graceful shutdown concept
Graceful shutdown means stopping new work and cleaning up before the app exits.Step 2: Identify the main goal
The goal is to avoid abrupt termination by closing servers and resources properly.Final Answer:
To stop accepting new requests and clean up resources before exiting -> Option DQuick Check:
Graceful shutdown = stop new work + cleanup [OK]
- Confusing graceful shutdown with automatic restart
- Thinking it improves performance directly
- Assuming it only logs requests
Solution
Step 1: Recall Node.js event listening syntax
Node.js uses process.on(event, handler) to listen for events.Step 2: Identify the correct event for uncaught exceptions
The event name is 'uncaughtException', so process.on('uncaughtException', handler) is correct.Final Answer:
process.on('uncaughtException', handler) -> Option AQuick Check:
Use process.on for events like uncaughtException [OK]
- Using process.catch instead of process.on
- Using wrong event names like 'error' for uncaughtException
- Confusing listen with on
const server = require('http').createServer();
process.on('SIGINT', () => {
console.log('Shutdown signal received');
server.close(() => {
console.log('Server closed');
process.exit(0);
});
});
server.listen(3000, () => console.log('Server running'));
What will be the output if you press Ctrl+C in the terminal?Solution
Step 1: Understand server start and signal handling order
The server logs 'Server running' when it starts listening. On Ctrl+C, SIGINT triggers the handler.Step 2: Trace the shutdown logs
On SIGINT, it logs 'Shutdown signal received', then closes the server, then logs 'Server closed'.Final Answer:
Server running\nShutdown signal received\nServer closed -> Option BQuick Check:
Startup log first, then SIGINT logs in order [OK]
- Mixing order of logs on startup and shutdown
- Assuming server closes before signal logs
- Ignoring asynchronous server.close callback
const server = require('http').createServer();
process.on('uncaughtException', (err) => {
console.error('Error:', err);
process.exit(1);
});
server.listen(3000);Solution
Step 1: Analyze error handling behavior
The handler logs the error but calls process.exit(1) immediately.Step 2: Check for graceful shutdown steps
It does not close the server before exiting, which can cause abrupt termination.Final Answer:
It exits immediately without closing the server -> Option CQuick Check:
Graceful shutdown requires closing server before exit [OK]
- Exiting without cleanup
- Ignoring server.close in error handlers
- Assuming logging is enough
SIGTERM and uncaughtException events, ensuring the server closes before exit. Which code snippet correctly achieves this?Solution
Step 1: Check handling of SIGTERM
process.on('SIGTERM', () => { server.close(() => process.exit(0)); }); process.on('uncaughtException', (err) => { console.error(err); server.close(() => process.exit(1)); }); closes the server and then exits, which is correct for graceful shutdown.Step 2: Check handling of uncaughtException
process.on('SIGTERM', () => { server.close(() => process.exit(0)); }); process.on('uncaughtException', (err) => { console.error(err); server.close(() => process.exit(1)); }); logs the error, closes the server, then exits with error code, ensuring cleanup.Final Answer:
process.on('SIGTERM', () => { server.close(() => process.exit(0)); }); process.on('uncaughtException', (err) => { console.error(err); server.close(() => process.exit(1)); }); -> Option AQuick Check:
Close server before exit on signals and errors [OK]
- Exiting immediately without closing server
- Not logging errors on uncaughtException
- Ignoring asynchronous server.close callback
