Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Express 3 error middleware not being called

I am trying to setup error handling for my express app and running into the following problem.

I defined an error middleware and add it as the last middleware:

// error handler
app.use(function(err, req, res, next) {

    console.log('JUST TESTING. ERROR HANLDER HAS BEEN CALLED...');
    next(err);
});

Now I would expect this middleware to be called whenever an error occurs:

app.get('/datenschutz', function(req, res, next){
        return next(new Error('Just testing')); // handle everything here
    });

However my middleware is never called! The browser does display the stack trace however. This seems that there is another middleware that is catching this error and processing it before I can do anything about it.

The problem is that I have no clue where this middleware could be defined, as I have a very simple setup:

// setup ssl for local testing
var
    app = express();

app.
    use(express.static(__dirname + '/public')).
    use(express.bodyParser()).
    use(express.cookieParser());

Why is my error handling middleware not being called? Where is this 'default' error handling taking place?

Thanks!

* EDIT * I see that the middleware is indeed working. However this is the case if I call it from another middleware function. However it is not being invoked if the error occurs inside a function defined as an express route (GET, POST, etc..). This is very strange. If I add my error middleware to the route callbacks it then works:

app.get('/testError', function(req, res, next){
        return next(new Error('Just testing')); // handle everything here
    }, function(err,req,res,next) {
        console.log('This error handler is called!!');
        return next();
    });

* EDIT 2 - FOUND ACCEPTABLE WORKAROUND ** I am surprised it has to be done this way. As I had read many entries/questions about error handling in express and never found this possibility mentioned. However it seems that if an error ocurrs inside a route callback regular error middleware handlers will not pick it up. You will need to define an error handler at route level.

app.all('*', function(err,req,res,next) {
        console.log('This is a global error handler at route level....');
        return next(err);
    });
like image 764
santiagoIT Avatar asked Nov 02 '12 15:11

santiagoIT


People also ask

How do you handle errors in middleware?

We call the error handling middleware by passing the error object to the next(error) function. We can define a chain of multiple error-handling middleware functions to one or more routes and attach them at the end of Express route definitions.

How does Express handle middleware?

js is a routing and Middleware framework for handling the different routing of the webpage and it works between the request and response cycle. Middleware gets executed after the server receives the request and before the controller actions send the response.


2 Answers

I had this problem as well, but I couldn't figure out why it wasn't working even though I set my error handler after the app.user(app.router). As it turns out, I already had an error handler that I wasn't aware of.

Specifically, if you use the express cli to generate an app like I did, it will automatically add in this in:

if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}

Unfortunately for me, I added a bit more middleware to my app, which consequently obscured this statement and thus prevented my custom error handler from being called.

Simply remove that and then it should work properly.

On a side note, I should mention that the original solution still worked - even with the app.use(express.errorHandler()).

app.all('*', function(err,req,res,next) {
    console.log('This is a global error handler at route level....');
    return next(err);
});
like image 73
amnah Avatar answered Oct 13 '22 23:10

amnah


Updated answer for Express 4 users from the Express 4 docs. See example from docs below. Note that app.router is deprecated and no longer used. I also added a dummy route to make the ordering clear:

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

var bodyParser = require('body-parser');

app.use(bodyParser());
app.get('/', function(req, res) {
    res.send('hello world');
})
app.use(function(err, req, res, next) {
  // logic
});

"

like image 31
skeller88 Avatar answered Oct 13 '22 22:10

skeller88