loadaverage
loadaverage

Reputation: 1035

How does exactly Express.js handle errors?

So, the trivial thing. All we know that Express has built-in default error handler that expect four arguments (err, req, res, next) to handle "synchronous exceptions" like ReferenceError, TypeError, etc:

UPDATE: this question is Express-specific, not about how to catch unhandled exceptions/etc. I want to know how in the first code block Express can handle user-defined exception. Second example with async. exception doesn't directly belongs to this question.

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

express.all('*', (req, res) => {
  throw new Error('my own error');
  res 
    .send('okay?');
});

express.use((err, req, res, next) => {
  console.error(err.stack);
  res 
    .status(503)
    .send('Express is still up and running');
}).listen(3000);

But not this:

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

express.all('*', (req, res) => {
  process.nextTick(() => {
    throw new Error('my own error');
  });
  res 
    .send('okay?');
});

express.use((err, req, res, next) => {
  console.error(err.stack);
  res 
    .status(503)
    .send('Won\'t be executed');
}).listen(3000);

But I'm curious about the realization of this handler.

I can't find anything like

process.on('uncaughtException'... or domains/Promises/cluster.

Maybe I miss something.

Can anyone clarify?

Upvotes: 1

Views: 766

Answers (1)

jsalonen
jsalonen

Reputation: 30481

There is a catch-all kind of block in Express's router that gets executed:

try {
  fn(req, res, next);
} catch (err) {
  next(err);
}

So in this block all exceptions are catched and translated to next() function calls with error parameter set to match the exception.

In more detail, when a request arrives to express:

  • app.handle() is called, which then determines router and calls router.handle()
  • router.handle() processes through layers and eventually matches your handler registered with express.all('*', ...) signature
  • handle_request (inside router's internal Layer module) calls your handler function as specified in the above try-catch block, effectively catching all possible exceptions and translating them into next calls.

Upvotes: 1

Related Questions