Bird
Raised Fist0
Node.jsframework~10 mins

Graceful shutdown on errors in Node.js - Step-by-Step Execution

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Concept Flow - Graceful shutdown on errors
Start Node.js app
Listen for errors
Error occurs?
NoContinue running
Yes
Log error
Close server connections
Cleanup resources
Exit process
The app runs and listens for errors. When an error happens, it logs it, closes connections, cleans up, then exits safely.
Execution Sample
Node.js
const server = app.listen(3000);
process.on('uncaughtException', (err) => {
  console.error('Error:', err);
  server.close(() => process.exit(1));
});
This code listens for uncaught errors, logs them, closes the server, then exits the app.
Execution Table
StepEventActionServer StateProcess State
1App startServer starts listeningOpenRunning
2No errorApp runs normallyOpenRunning
3Uncaught error occursError caught by handlerOpenRunning
4Error loggedConsole outputs error messageOpenRunning
5Server closingserver.close() calledClosingRunning
6Server closedCallback triggers process.exit(1)ClosedExiting
7Process exitApp stopsClosedStopped
💡 Process exits after server closes to ensure no new requests are accepted.
Variable Tracker
VariableStartAfter ErrorAfter server.close()Final
serverListeningListeningClosingClosed
process.stateRunningRunningExitingStopped
Key Moments - 3 Insights
Why do we call server.close() before process.exit()?
Calling server.close() stops new connections and finishes existing ones before exiting, preventing abrupt termination. See execution_table steps 5 and 6.
What happens if we call process.exit() immediately on error?
The app stops instantly, possibly dropping active requests or leaving resources open. The table shows graceful shutdown waits for server to close first.
How does the error handler catch uncaught exceptions?
The process.on('uncaughtException') listens globally for errors not caught elsewhere, shown in execution_table step 3.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the server state at step 5?
AClosed
BOpen
CClosing
DStopped
💡 Hint
Check the 'Server State' column at step 5 in the execution_table.
At which step does the process start exiting?
AStep 4
BStep 6
CStep 5
DStep 7
💡 Hint
Look for when process.exit(1) is called in the 'Action' column.
If server.close() was not called, what would happen to the process state after error?
AProcess would exit immediately
BServer would close automatically
CProcess would keep running
DError would not be logged
💡 Hint
Refer to key_moments about calling process.exit() immediately without server.close().
Concept Snapshot
Graceful shutdown on errors:
- Listen for uncaught errors with process.on('uncaughtException')
- Log the error for debugging
- Call server.close() to stop new requests and finish ongoing ones
- After server closes, call process.exit() to stop the app
- This prevents abrupt termination and resource leaks
Full Transcript
This visual execution shows how a Node.js app handles errors gracefully. The app starts and listens for requests. If an uncaught error happens, the error handler logs it, then calls server.close() to stop accepting new connections and finish current ones. Once the server closes, the app calls process.exit() to stop running. This sequence avoids sudden crashes and cleans up resources properly. Variables like server state and process state change step by step, showing the shutdown flow clearly.

Practice

(1/5)
1. What is the main purpose of implementing a graceful shutdown in a Node.js application?
easy
A. To restart the server automatically after an error
B. To log all incoming requests for debugging
C. To increase the server's performance under load
D. To stop accepting new requests and clean up resources before exiting

Solution

  1. Step 1: Understand graceful shutdown concept

    Graceful shutdown means stopping new work and cleaning up before the app exits.
  2. Step 2: Identify the main goal

    The goal is to avoid abrupt termination by closing servers and resources properly.
  3. Final Answer:

    To stop accepting new requests and clean up resources before exiting -> Option D
  4. Quick Check:

    Graceful shutdown = stop new work + cleanup [OK]
Hint: Remember: graceful shutdown means clean exit, not restart [OK]
Common Mistakes:
  • Confusing graceful shutdown with automatic restart
  • Thinking it improves performance directly
  • Assuming it only logs requests
2. Which of the following is the correct way to listen for an uncaught exception to trigger graceful shutdown in Node.js?
easy
A. process.on('uncaughtException', handler)
B. process.addListener('error', handler)
C. process.listen('uncaughtException', handler)
D. process.catch('uncaughtException', handler)

Solution

  1. Step 1: Recall Node.js event listening syntax

    Node.js uses process.on(event, handler) to listen for events.
  2. Step 2: Identify the correct event for uncaught exceptions

    The event name is 'uncaughtException', so process.on('uncaughtException', handler) is correct.
  3. Final Answer:

    process.on('uncaughtException', handler) -> Option A
  4. Quick Check:

    Use process.on for events like uncaughtException [OK]
Hint: Use process.on(event, handler) for error events [OK]
Common Mistakes:
  • Using process.catch instead of process.on
  • Using wrong event names like 'error' for uncaughtException
  • Confusing listen with on
3. Consider this Node.js code snippet handling graceful shutdown:
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?
medium
A. Shutdown signal received\nServer running\nServer closed
B. Server running\nShutdown signal received\nServer closed
C. Server running\nServer closed\nShutdown signal received
D. Server closed\nShutdown signal received\nServer running

Solution

  1. 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.
  2. Step 2: Trace the shutdown logs

    On SIGINT, it logs 'Shutdown signal received', then closes the server, then logs 'Server closed'.
  3. Final Answer:

    Server running\nShutdown signal received\nServer closed -> Option B
  4. Quick Check:

    Startup log first, then SIGINT logs in order [OK]
Hint: Remember: server.listen logs first, then signal handler logs [OK]
Common Mistakes:
  • Mixing order of logs on startup and shutdown
  • Assuming server closes before signal logs
  • Ignoring asynchronous server.close callback
4. Given this code snippet for graceful shutdown, what is the main problem?
const server = require('http').createServer();
process.on('uncaughtException', (err) => {
  console.error('Error:', err);
  process.exit(1);
});
server.listen(3000);
medium
A. It listens on the wrong port
B. It does not log the error properly
C. It exits immediately without closing the server
D. It uses the wrong event name for errors

Solution

  1. Step 1: Analyze error handling behavior

    The handler logs the error but calls process.exit(1) immediately.
  2. Step 2: Check for graceful shutdown steps

    It does not close the server before exiting, which can cause abrupt termination.
  3. Final Answer:

    It exits immediately without closing the server -> Option C
  4. Quick Check:

    Graceful shutdown requires closing server before exit [OK]
Hint: Always close servers before calling process.exit [OK]
Common Mistakes:
  • Exiting without cleanup
  • Ignoring server.close in error handlers
  • Assuming logging is enough
5. You want to implement a graceful shutdown that handles both SIGTERM and uncaughtException events, ensuring the server closes before exit. Which code snippet correctly achieves this?
hard
A. process.on('SIGTERM', () => { server.close(() => process.exit(0)); }); process.on('uncaughtException', (err) => { console.error(err); server.close(() => process.exit(1)); });
B. process.on('SIGTERM', () => { server.close(); }); process.on('uncaughtException', () => { process.exit(1); });
C. process.on('SIGTERM', () => { process.exit(0); }); process.on('uncaughtException', () => { process.exit(1); });
D. process.on('SIGTERM', () => { console.log('Terminated'); }); process.on('uncaughtException', (err) => { console.error(err); });

Solution

  1. 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.
  2. 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.
  3. Final Answer:

    process.on('SIGTERM', () => { server.close(() => process.exit(0)); }); process.on('uncaughtException', (err) => { console.error(err); server.close(() => process.exit(1)); }); -> Option A
  4. Quick Check:

    Close server before exit on signals and errors [OK]
Hint: Always close server before exit on signals and errors [OK]
Common Mistakes:
  • Exiting immediately without closing server
  • Not logging errors on uncaughtException
  • Ignoring asynchronous server.close callback