CodingNic

Process Management & Reliability

Why a Single Process Isn't Enough

Process Management & Reliability 10 min read

Why a Single Process Isn't Enough

Objectives

By the end of this lesson, you should be able to:

  • Explain what happens to an Express app when an uncaught exception occurs outside a request handler
  • Explain why error-handling middleware (Course 3) doesn’t catch every kind of error
  • Recognize why a running production application needs something watching the process itself

💡 Why this matters: Course 3 built error-handling middleware that turns a thrown error into a clean HTTP response. That middleware only runs for errors thrown during a request, an error thrown anywhere else, a stray callback, a timer, a background job, crashes the entire Node.js process, taking every other in-flight request down with it.

⚠️ A note on verification: every snippet and every output in this lesson was actually run.

A Route That Crashes the Whole Server

javascript
const express = require('express');
const app = express();

app.get('/', (req, res) => res.json({ status: 'ok' }));

app.get('/crash', (req, res) => {
  setTimeout(() => {
    const user = undefined;
    console.log(user.name); // throws, but asynchronously, outside Express's request cycle
  }, 10);
  res.json({ status: 'processing' });
});

app.listen(6000, () => console.log(`Server ${process.pid} listening`));

The bug here, user.name where user is undefined, is exactly the kind of programmer error Course 3, Module 9 covered logging for. The difference is where it happens, inside a setTimeout callback, entirely outside the request/response cycle Express’s error-handling middleware watches.

What Actually Happens

text
--- before crash ---
{"status":"ok"}
{"status":"processing"}

TypeError: Cannot read properties of undefined (reading 'name')
    at Timeout._onTimeout (crashy.js:11:22)
    ...

--- after crash, is process still alive? ---
process died
connection refused, server is down

The /crash request itself returned successfully, {"status":"processing"}, the crash happened ten milliseconds later, asynchronously, after the response was already sent. Node.js printed the stack trace and exited entirely, every other request the server might have been handling, and every future request, is gone, the process itself no longer exists.

Why Error-Handling Middleware Doesn’t Save This

Express’s error-handling middleware (Course 3, Module 9) catches errors passed to next(err), or thrown synchronously inside a route handler, it has no way to catch an exception thrown later, inside a callback that’s no longer part of any request. This isn’t a bug in Express, it’s a fundamental limit of what a single process, with no supervisor watching it, can recover from on its own.

What This Means for a Real Deployment

A production application needs something outside the application itself, watching whether the process is still alive, and restarting it immediately if it isn’t. This is the entire subject of this module: Node’s built-in cluster module (running multiple processes, so one crashing doesn’t take everything down), graceful shutdown (finishing in-flight work cleanly when a process does need to stop), and PM2 (a process manager that restarts a crashed process automatically, without a person needing to notice and intervene).

Try It

  1. Run the /crash route above, and confirm the server process actually exits, not just the one request.
  2. Identify a place in your own code, from an earlier module in this track, where an error could occur outside of Express’s request cycle (a timer, a background task, an event listener).
  3. Explain, in one or two sentences, why “write more careful code” isn’t a complete answer to this problem, even for a team that writes very careful code.

Recap

  • An uncaught exception outside the request/response cycle crashes the entire Node.js process, not just the one request that triggered it.
  • Express’s error-handling middleware only catches errors within its own request cycle, it can’t protect against this.
  • A real deployment needs something watching the process itself, ready to restart it immediately, this module builds exactly that.

Next lesson: Node’s cluster module, running more than one process, so a single crash doesn’t take the whole application down.