Script Valley
Node.js: The Complete Runtime
Async JavaScript in Node.jsLesson 2.5

Handling errors in async Node.js code the right way

try/catch in async functions, unhandledRejection, uncaughtException, error objects, operational vs programmer errors, process error events

Two Categories of Errors

Operational errors are expected failures: missing files, network timeouts, invalid user input. Handle them and continue. Programmer errors are bugs: calling a function with the wrong type, accessing a property on undefined. Fix the code; do not try to recover at runtime.

Catching Async Errors

async function loadConfig(path) {
  try {
    const raw = await fs.readFile(path, 'utf8');
    return JSON.parse(raw);
  } catch (err) {
    if (err.code === 'ENOENT') {
      return {}; // file not found is recoverable
    }
    throw err; // re-throw unexpected errors
  }
}

Process-Level Safety Net

process.on('unhandledRejection', (reason, promise) => {
  console.error('Unhandled rejection:', reason);
  process.exit(1);
});

process.on('uncaughtException', (err) => {
  console.error('Uncaught exception:', err);
  process.exit(1);
});

Do not use uncaughtException to swallow errors. After an uncaught exception the process is in an undefined state. Log, then exit. A process manager (PM2, systemd) handles the restart.

Handling errors in async Node.js code the right way — Async JavaScript in Node.js — Node.js: The Complete Runtime — Script Valley — Script Valley