Error-handling middleware doesn't always work Error-handling middleware doesn't always work express express

Error-handling middleware doesn't always work


When you define routes/middleware, the path you specify is used to see if it matches with incoming requests. Your request will always be routed to the first match. A request might have multiple matches, so order matters here. You can hit the next matching route/middleware by calling the next() function.

When you mount middleware using app.use without specifying a path, every path is eligible to hit that middleware. So, if it's the first thing you mount, every request will use that middleware.

If you want a catch all error handler, you'll want the opposite - you should mount middleware at the very end of your route definitions. You'll need to call the next function in your handler to actually reach this middleware:

app.get('/hello', function(req, res, next) {  ...  // Let's pretend that there was some error  next()});// After all of your route definitions...app.use(function(req, res) {  res.status(500).send('something broke!');})

Note that if no route exists for the current path, you will also hit this catch all middleware.


Docs

http://expressjs.com/en/guide/error-handling.html

You define error-handling middleware last, after other app.use() and routes calls; for example:

var bodyParser = require('body-parser');var methodOverride = require('method-override');app.use(bodyParser());app.use(methodOverride());app.use(function(err, req, res, next) {  // logic});

The Internal

For ease of understanding, you can imagine the pipeline. When your controller receives a request, inside Express, it looks like this

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

So, then your code throw error, it will call next with err. Basically, it's the same as call next(new Error()). After that, express trying to find next middleware with 4 arguments in middleware pipeline. In your situation error handler declared before your shady controller, so he doesn't involved.

Technically, there is no difference between the controller and middlewares. Optionally you can pass in the controller next parameter , and call it to pass through the pipeline further. If you don't call next(), you finish processing the request.